文档章节

javascript严格模式

开源oschina
 开源oschina
发布于 2014/12/24 10:02
字数 2635
阅读 38
收藏 1

ECMAScript 5 最早引入了“严格模式”(strict mode)的概念。通过严格模式,可以在函数内部

选择进行较为严格的全局或局部的错误条件检测。使用严格模式的好处是可以提早知道代码中

存在的错误,及时捕获一些可能导致编程错误的ECMAScript 行为。

理解严格模式的规则非常重要,ECMAScript 的下一个版本将以严格模式为基础制定。支持严格模

式的浏览器包括IE10+、Firefox 4+、Safari 5.1+和Chrome。

 

1.选择使用

要选择进入严格模式,可以使用严格模式的编译指示(pragma),实际上就是一个不会赋给任何变

量的字符串:

"use strict";

这种语法(从ECMAScript 3 开始支持)可以向后兼容那些不支持严格模式的JavaScript 引擎。支持

严格模式的引擎会启动这种模式,而不支持该模式的引擎就当遇到了一个未赋值的字符串字面量,会忽

略这个编译指示。

如果是在全局作用域中(函数外部)给出这个编译指示,则整个脚本都将使用严格模式。换句话说,

如果把带有这个编译指示的脚本放到其他文件中,则该文件中的JavaScript 代码也将处于严格模式下。

也可以只在函数中打开严格模式,就像下面这样:

function doSomething(){"use strict";//其他代码}

 

如果你没有控制页面中所有脚本的权力,建议只在需要测试的特定函数中开启严格模式。

 

2 .变量

在严格模式下,什么时候创建变量以及怎么创建变量都是有限制的。首先,不允许意外创建全局变

量。在非严格模式下,可以像下面这样创建全局变量:

 

//未声明变量//非严格模式:创建全局变量//严格模式:抛出ReferenceErrormessage = "Hello world! ";

 

即使message 前面没有var 关键字,即使没有将它定义为某个全局对象的属性,也能将message

创建为全局变量。但在严格模式下,如果给一个没有声明的变量赋值,那代码在执行时就会抛出

ReferenceError。

其次,不能对变量调用delete 操作符。非严格模式允许这样操作,但会静默失败(返回false)。

而在严格模式下,删除变量也会导致错误。

 

//删除变量//非严格模式:静默失败//严格模式:抛出ReferenceErrorvar color = "red";delete color;

 

严格模式下对变量名也有限制。特别地,不能使用implements、interface、let、package、

private、protected、public、static 和yield 作为变量名。这些都是保留字,将来的ECMAScript

版本中可能会用到它们。在严格模式下,用以上标识符作为变量名会导致语法错误。

 

3.对象

在严格模式下操作对象比在非严格模式下更容易导致错误。一般来说,非严格模式下会静默失败的
情形,在严格模式下就会抛出错误。因此,在开发中使用严格模式会加大早发现错误的可能性。
在下列情形下操作对象的属性会导致错误:
 为只读属性赋值会抛出TypeError;
 对不可配置的(nonconfigurable)的属性使用delete 操作符会抛出TypeError;
 为不可扩展的(nonextensible)的对象添加属性会抛出TypeError。
使用对象的另一个限制与通过对象字面量声明对象有关。在使用对象字面量时,属性名必须唯一。
例如:

复制代码

//重名属性//非严格模式:没有错误,以第二个属性为准//严格模式:抛出语法错误var person = {
name: "Nicholas",
name: "Greg"};

复制代码

这里的对象person 有两个属性,都叫name。在非严格模式下,person 对象的name 属性值是第
二个,而在严格模式下,这样的代码会导致语法错误。

 

4.函数

首先,严格模式要求命名函数的参数必须唯一。以下面这个函数为例:

//重名参数//非严格模式:没有错误,只能访问第二个参数//严格模式:抛出语法错误function sum (num, num){//do something}

在非严格模式下,这个函数声明不会抛出错误。通过参数名只能访问第二个参数,要访问第一个参

数必须通过arguments 对象。

在严格模式下,arguments 对象的行为也有所不同。在非严格模式下,修改命名参数的值也会反

映到arguments 对象中,而严格模式下这两个值是完全独立的。例如:

复制代码

//修改命名参数的值//非严格模式:修改会反映到arguments 中//严格模式:修改不会反映到arguments 中function showValue(value){
value = "Foo";
alert(value); //"Foo"alert(arguments[0]); //非严格模式:"Foo"//严格模式:"Hi"}
showValue("Hi");

复制代码

以上代码中,函数showValue()只有一个命名参数value。调用这个函数时传入了一个参数"Hi",

这个值赋给了value。而在函数内部,value 被改为"Foo"。在非严格模式下,这个修改也会改变

arguments[0]的值,但在严格模式下,arguments[0]的值仍然是传入的值。

另一个变化是淘汰了arguments.callee 和arguments.caller。在非严格模式下,这两个属

性一个引用函数本身,一个引用调用函数。而在严格模式下,访问哪个属性都会抛出TypeError。

例如:

复制代码

//访问arguments.callee//非严格模式:没有问题//严格模式:抛出TypeErrorfunction factorial(num){if (num <= 1) {return 1;
} else {return num * arguments.callee(num-1)
}
}var result=factorial(5);

复制代码

类似地,尝试读写函数的caller 属性,也会导致抛出TypeError。所以,对于上面的例子而言,

访问factorial.caller 也会抛出错误。

与变量类似,严格模式对函数名也做出了限制,不允许用implements、interface、let、package、

private、protected、public、static 和yield 作为函数名。

对函数的最后一点限制,就是只能在脚本的顶级和在函数内部声明函数。也就是说,在if 语句中

声明函数会导致语法错误:

复制代码

//在if 语句中声明函数//非严格模式:将函数提升到if 语句外部//严格模式:抛出语法错误if (true){function doSomething(){//...}
}

复制代码

在非严格模式下,以上代码能在所有浏览器中运行,但在严格模式下会导致语法错误。

 

5.eval()

饱受诟病的eval()函数在严格模式下也得到了提升。最大的变化就是它在包含上下文中不再创建

变量或函数。例如:

复制代码

//使用eval()创建变量//非严格模式:弹出对话框显示10//严格模式:调用alert(x)时会抛出ReferenceErrorfunction doSomething(){
eval("var x=10");
alert(x);
}

复制代码

如果是在非严格模式下,以上代码会在函数doSomething()中创建一个局部变量x,然后alert()

还会显示该变量的值。但在严格模式下,在doSomething()函数中调用eval()不会创建变量x,因此

调用alert()会导致抛出ReferenceError,因为x 没有定义。

可以在eval()中声明变量和函数,但这些变量或函数只能在被求值的特殊作用域中有效,随后就

将被销毁。因此,以下代码可以运行,没有问题:

"use strict";var result = eval("var x=10, y=11; x+y");
alert(result); //21

这里在eval()中声明了变量x 和y,然后将它们加在一起,返回了它们的和。于是,result 变

量的值是21,即x 和y 相加的结果。而在调用alert()时,尽管x 和y 已经不存在了,result 变量

的值仍然是有效的。

 

6.eval与arguments

严格模式已经明确禁止使用eval 和arguments 作为标识符,也不允许读写它们的值。例如:

//把eval 和arguments 作为变量引用//非严格模式:没问题,不出错//严格模式:抛出语法错误var eval = 10;var arguments = "Hello world!";

在非严格模式下,可以重写eval,也可以给arguments 赋值。但在严格模式下,这样做会导致语

法错误。不能将它们用作标识符,意味着以下几种使用方式都会抛出语法错误:

 使用var 声明;

 赋予另一个值;

 尝试修改包含的值,如使用++;

 用作函数名;

 用作命名的函数参数;

 在try-catch 语句中用作例外名。

 

7.抑制this

JavaScript 中一个最大的安全问题,也是最容易让人迷茫的地方,就是在某些情况下如何抑制this

的值。在非严格模式下使用函数的apply()或call()方法时,null 或undefined 值会被转换为全局

对象。而在严格模式下,函数的this 值始终是指定的值,无论指定的是什么值。例如:

复制代码

//访问属性//非严格模式:访问全局属性//严格模式:抛出错误,因为this 的值为nullvar color = "red";function displayColor(){
alert(this.color);
}
displayColor.call(null);

复制代码

以上代码向displayColor.call()中传入了null,如果在是非严格模式下,这意味着函数的this

值是全局对象。结果就是弹出对话框显示"red"。而在严格模式下,这个函数的this 的值是null,因

此在访问null 的属性时就会抛出错误。

 

8.其他变化

严格模式还有其他一些变化,希望读者也能留意。首先是抛弃了with 语句。非严格模式下的with

语句能够改变解析标识符的路径,但在严格模式下,with 被简化掉了。因此,在严格模式下使用with

会导致语法错误。

//with 的语句用法//非严格模式:允许//严格模式:抛出语法错误with(location){
alert(href);
}

严格模式也去掉了JavaScript 中的八进制字面量。以0 开头的八进制字面量过去经常会导致很多错

误。在严格模式下,八进制字面量已经成为无效的语法了。

//使用八进制字面量//非严格模式:值为8//严格模式:抛出语法错误var value = 010;

ECMAScript 5 也修改了严格模式下parseInt()的行为。如今,八进制字面量在

严格模式下会被当作以0 开头的十进制字面量。例如:

//使用parseInt()解析八进制字面量//非严格模式:值为8//严格模式:值为10var value = parseInt("010");

 


© 著作权归作者所有

开源oschina

开源oschina

粉丝 42
博文 58
码字总数 25338
作品 0
九龙坡
私信 提问
JavaScript语法支持严格模式:”use strict”

JavaScript语法支持严格模式:”use strict” 如果给JavaScript代码标志为“严格模式”,则其中运行的所有代码都必然是严格模式下的。 其一:如果在语法检测时发现语法问题,则整个代码块失效...

造化玉碟
2014/04/28
457
0
现代 JavaScript 教程 — "use strict" 现代模式

现代模式,"use strict" 长久以来,JavaScript 不断向前发展且并未带来任何兼容性问题。新的特性被加入,旧的功能也没有改变。 这么做有利于兼容旧代码,但缺点是 JavaScript 创造者的任何错...

技术漫谈
10/02
0
0
JavaScript闪电入门教程

如需在 HTML 页面中插入JavaScript,请使用

材大难为用
01/25
0
0
10个流行的JavaScript面试题

译者:前端小智 原文:medium.com/@jlanne119/… 为了保证可读性,本文采用意译而非直译 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 1.如何理解 JS 中的关键字? JS 初...

前端小智
06/19
0
0
Javascript 严格模式详解

一、概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。 设立"严格模式"的目的,主要有以下几...

开源oschina
2014/12/24
80
3

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 7系统增加swap

转载请注明文章出处:CentOS 7系统增加swap swap是位于磁盘上的特殊文件(或分区),属于“虚拟内存”的一部分。通俗点就是内存的备胎,内存充足的情况下,基本上没swap什么事(和设置有关)...

tlanyan
18分钟前
2
0
基于Prometheus和Grafana的监控平台 - 环境搭建

相关概念 微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics。 Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。比如我们说...

JAVA日知录
59分钟前
5
0
PHP运行时全局构造体

struct _php_core_globals { zend_bool magic_quotes_gpc; // 是否对输入的GET/POST/Cookie数据使用自动字符串转义。 zend_bool magic_quotes_runtime; //是否对运行时从外部资源产生的数据使...

冻结not
今天
4
0
webpack插件html-webpack-plugin

本文转载于:专业的前端网站→webpack插件html-webpack-plugin 1、插件安装 npm install html-webpack-plugin --save-dev 2、插件使用 webpack.config.js配置文件为: var htmlWebpackPlugin=...

前端老手
今天
6
0
数据挖掘

zhengchen1996
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部