严格模式:使用严格模式的好处是可以提早知道代码中存在的错误,及时捕获一些可能导致编程错误的 ECMAScript 行为。
严格模式的选择使用
严格模式的编译指示(pragma): “use strict”;,支持严格模式的引擎会启动这种模式,而不支持该模式的引擎就当遇到了一个未赋值的字符串字面量,会忽略这个编译指示。
- 在全局作用域中(函数外部)给出这个编译指示,则整个脚本都将使用严格模式。
- 在函数作用域中给出这个编译指示,则这个函数将使用严格模式
function test () {"use strict";...}
严格模式的规范
变量
不允许意外创建全局变量,给一个没有声明的变量赋值,那代码在执行时就会抛出 ReferenceError
// 未声明变量// 非严格模式:创建全局变量// 严格模式:抛出 ReferenceErrormessage = "Hello world! ";
不能对变量调用 delete 操作符
//删除变量//非严格模式:静默失败//严格模式:抛出 ReferenceErrorvar color = "red";delete color;
严格模式下对变量名也有限制,不能使用 implements、interface、let、package、 private、protected、public、static 和 yield 标识符作为变量名,使用以上标识符作为变量名会导致语法错误。
对象
为只读属性赋值会抛出 TypeError
- 对不可配置的(nonconfigurable)的属性使用 delete 操作符会抛出 TypeError
- 为不可扩展的(nonextensible)的对象添加属性会抛出 TypeError
使用对象字面量时,属性名必须唯一
// 重名属性// 非严格模式:没有错误,以第二个属性为准// 严格模式:抛出语法错误var person = {name: "Nicholas",name: "Greg"};
函数
严格模式要求命名函数的参数必须唯一
//重名参数//非严格模式:没有错误,只能访问第二个参数//严格模式:抛出语法错误function sum (num, num){// todo}
在非严格模式下,修改命名参数的值也会反映到arguments对象中,而严格模式下这两个值是完全独立的
//修改命名参数的值//非严格模式:修改会反映到 arguments 中//严格模式:修改不会反映到 arguments 中function showValue(value) {value = "Foo";console.log(value); //"Foo"console.log(arguments[0]); //非严格模式:"Foo",严格模式:"Hi"}showValue("Hi");
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);
严格模式对函数名也做出了限制,不允许用implements、interface、let、package、private、protected、public、static 和 yield 作为函数名
只能在脚本的顶级和在函数内部声明函数
//在 if 语句中声明函数//非严格模式:将函数提升到 if 语句外部//严格模式:抛出语法错误if (true){function doSomething(){// todo}}
eval( )
在严格模式中,它在包含上下文中不再创建变量或函数
//使用 eval()创建变量//非严格模式:弹出对话框显示 10//严格模式:调用 alert(x)时会抛出 ReferenceErrorfunction doSomething(){eval("var x=10");alert(x);}
可以在 eval()中声明变量和函数,但这些变量或函数只能在被求值的特殊作用域中有效,随后就将被销毁
"use strict";var result = eval("var x=10, y=11; x+y");alert(result); // 21
eval 和 arguments
严格模式已经明确禁止使用 eval 和 arguments 作为标识符,也不允许读写它们的值。
// 把 eval 和 arguments 作为变量引用// 非严格模式: 没问题,不出错// 严格模式: 抛出语法错误var eval = 10;var arguments = "Hello world!";
抑制this
在非严格模式下使用函数的 apply()或 call()方法时,null 或 undefined 值会被转换为全局 对象。而在严格模式下,函数的 this 值始终是指定的值,无论指定的是什么值。
// 访问属性 // 非严格模式: 传入null, 函数的this值是全局对象 // 严格模式: 抛出错误,因为this的值为 null var color = "red"; function displayColor(){ alert(this.color); } displayColor.call(null);其他变化
非严格模式下的 with 语句能够改变解析标识符的路径。严格模式下,with 被简化掉了
//with 的语句用法 //非严格模式:允许 //严格模式:抛出语法错误 with(location){ alert(href); }严格模式去掉了 JavaScript 中的八进制字面量
//使用八进制字面量 //非严格模式:值为 8 //严格模式:抛出语法错误 var value = 010;严格模式下 parseInt()的行为,八进制字面量在严格模式下会被当作以 0 开头的十进制字面量
//使用 parseInt()解析八进制字面量 //非严格模式:值为 8 //严格模式:值为 10 var value = parseInt("010");
