严格模式是区分ECMA3和ECMA5的一个重要标识,也是对Javascript语法要求更严的一种表现。
其中的区别
定义
ECMA5中只允许,有且只有一个定义,那就是:"use strict";
。
作用域
当你郑重的写下:"use strict";
后,你之后的代码将采用严格模式。而我这里所说的之后是指的当前作用域(或者说当前函数内)你这条语句之后;
如果你超出当前作用域则不采用严格模式。如:
不建议把"use strict";
写在中间位置,应该写在每个函数的最上方。
限制
严格模式下,有一些变量是不允许被定义,有一些调用是不被允许的。
关键字
未来可能使用到的关键字,如:implements, interface, let, package, private, protected, public, static, yield.
他们是不可以做变量被声明,且不能作为函数参数名。
8进制数字
以0开头的数字且0后的每个数字不能超过7,如:007 => 7。
当然,这也是为什么要强调,在使用parseInt的时候,后面加载转换的进制类型,如:parseInt('08aa', 10);
没有声明的变量
定义一个没有声明的变量(一般指代的是定义了一个全局变量),如:
但有种情况很特殊:
定义一个read-only属性
但是,如果属性是可配置的,那么就还是可以通过Object.defineProperty
去修改的。如:
另外一种情况也可以改变read-only属性。
创建一个没有扩展的对象
eval 和 arguments
当然,在严格模式下,eval和arguments也被当做关键字。
就像第一条讲的一样,她俩是不能作为变量声明的。当然,作为对象的属性是可以的,比如:var foo = {}; foo.eval = 10;
需要注意一点的是,arguments不能当做函数的属性被调用,比如:function foo(){ console.log(foo.arguments); }
先来说说eval
看到上面的例子,我们就清楚了知道了ECMA5中的eval不同点就在于, ECMA5下eval其实是一个子函数环境(你可以理解为里面又嵌套了一个执行函数,不过,如果没写”use strict”;那么它使用的是非严格模式)。非严格模式下,相当于你在当前函数内执行了一段代码,只是this不指向的当前函数而是全局变量。
再说说arguments
同样,看到上面的例子后,我们就知道,在ECMA5中arguments的不同点就在于, arguments其实相当于一个静态拷贝,不再是以前的引用了。也就是说,修改arguments不会影响变量。
caller 和 callee
caller和callee是ES3中函数的标识。
- arguments.caller指代的是调用当前执行函数的函数。
- arguments.callee指代的是当前执行函数,经常被使用在匿名函数中。
那在ES5中严格模式下呢?
很不幸的消息是,arguments.callee和arguments.caller将在不能ES5中的严格模式下被使用。
对于arguments.callee
arguments.callee存在的意义也其实也不是很大,相反如果你直接用函数名,还可以减少几个bit的字节呢(无论压缩与否)?!
对于arguments.caller
arguments.caller在ES3中的定义并不规范。既不是函数的直接属性,也不是变量对象(arguments object)的属性。而且有可能被弃用,所有不推荐使用。
注意一下,另外一个需要提及的ES5变动,ES5中可以使用关键字作为属性名。但是在ES3中不能。比如:foo = { super:fun.., function: fun.. }
就可以正常使用。
重复
重复的对象属性名和函数参数是行不通的。如:
同理,下面几种情况也是行不通的:
当然,非严格模式下,它们也是行不通的。
with
不准用with,;-)。pass…
this值
严格模式下,this值不强制转换为一个对象。当this的值为null或者undefined时,它不会转换成全局对象(global object)。当为原生值(primitive values)时,也不会强制转换为对象。
这样,通过Function.prototype.apply和Function.prototype.call调用的方式的this,可以为任意值。
这里需要注意的是,当函数不是通过new去创建时,在里面使用this.x将会报错。因为this为undefined。
所以,可以得到一个判断是否当前是严格模式的表达式
后记
以上是我个人的理解,仅供参考,不一定讲得很对,欢迎指出我其中的错误,本人不甚感激。
参考
http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/