深入理解JavaScript严格模式
JavaScript严格模式(Strict Mode)是ECMAScript 5引入了一种新的执行模式,主要用于消除JavaScript语言的一些不合理、不严谨之处,减少一些怪异行为。
启用严格模式
全局启用严格模式
要想在全局范围启用严格模式,需要在JavaScript源码文件的顶部添加如下代码:
"use strict";
整个源码文件都会进入严格模式,包括该文件导入的所有模块也会进入严格模式。
局部启用严格模式
对于某个JS函数或某个代码块,也可以开启独立的严格模式。需要在函数或代码块的开头添加如下代码:
function strictModeExample1() {
"use strict";
// 代码块
}
(function(){
"use strict";
// 代码块
})();
严格模式带来的变化
1. 变量必须先声明,再使用
在非严格模式下,如果直接使用未经声明的变量,JavaScript会隐式地将其创建为一个全局变量,导致在某些情况下出现意外的变量名冲突。严格模式下,如果直接使用未经声明的变量,JavaScript直接抛出一个引用错误(ReferenceError)。
function strictModeExample2() {
"use strict";
var a = 1;
b = 2; // 直接使用未经声明的变量,在严格模式下,JavaScript抛出一个ReferenceError错误。
console.log(a, b);
}
strictModeExample2(); // 引用错误:b is not defined
2. 对象字面量中定义的重复属性会报错
在非严格模式下,如果一个对象字面量中定义了多个同名属性,则只会保留最后一个属性的值,其它属性都被忽略。在严格模式下,如果一个对象字面量中定义了多个同名属性,JavaScript会抛出一个语法错误(SyntaxError)。
function strictModeExample3() {
"use strict";
var data = {
name: 'Lucy',
email: 'lucy@example.com',
name: 'Lily' // 对象字面量中定义的重复属性,在严格模式下,JavaScript会抛出一个SyntaxError错误。
};
console.log(data);
}
strictModeExample3(); // 语法错误:Duplicate data property in object literal not allowed in strict mode
3. eval函数不会在其所在的作用域中作为本地变量绑定
非严格模式下,eval函数所执行的代码字符串中声明的变量会被添加到eval函数所在的作用域中。在严格模式下,eval函数不会在其所在的作用域中作为一个本地变量绑定,而是在一个新的、私有的作用域中执行,这意味着eval函数不能读写执行环境中的本地变量。
function strictModeExample4() {
"use strict";
eval('var foo = 1');
console.log(foo); // 严格模式下,变量foo不会添加到当前作用域中,JavaScript会抛出一个引用错误。
}
strictModeExample4(); // 引用错误:foo is not defined
4. 函数的参数名不能重复
在非严格模式下,如果两个参数的名称相同,JavaScript会默认忽略第二个参数的定义,这可能导致意料之外的行为。在严格模式下,如果两个参数名称相同,JavaScript会抛出一个语法错误(SyntaxError)。
function strictModeExample5(arg1, arg1) { // 在函数参数中定义的重复变量名称,在严格模式下,JavaScript会抛出一个SyntaxError错误。
"use strict";
console.log(arg1, arg1);
}
strictModeExample5(1, 2); // 语法错误:Duplicate parameter name not allowed in strict mode
5. 禁止this关键字指向全局对象
在非严格模式下,如果一个函数在全局上下文中调用,函数内部的this关键字会被绑定到全局对象上。在严格模式下,如果一个函数在全局上下文中调用,函数内部的this关键字会被绑定到undefined。
function strictModeExample6() {
"use strict";
console.log(this); // 在全局作用域中调用函数,严格模式下,函数内部的this关键字会被绑定到undefined。
}
strictModeExample6.call(null); // 输出:undefined
6. 运行eval或Function代码时,不会在其所在的外层作用域中创建新的变量或函数
在非严格模式下,eval或Function代码所在的作用域可以动态地创建新的变量或函数,这可能导致应用程序安全性方面的隐患。在严格模式下,eval或Function代码执行时,不会在其所在的外层作用域中创建新的变量或函数。
function strictModeExample7() {
"use strict";
var data = '0000';
eval('var data = "1111"');
console.log(data); // 在非严格模式下,data变量的作用域被改变,输出结果为1111。但在严格模式下,eval代码不会在其外层作用域中创建新的变量,输出结果仍为0000。
}
strictModeExample7(); // 输出:0000
示例
示例1:禁止使用with语句
严格模式下禁止使用with语句,因为该语句会增加程序的安全隐患,且容易出现引用错误。
function strictExample1() {
"use strict";
var myObject = {foo: 'bar'};
with(myObject) { // 严格模式下,使用with语句会抛出一个语法错误
console.log(foo);
}
}
strictExample1(); // 抛出语法错误:Strict mode code may not include a with statement
示例2:禁止在非函数代码块内声明函数
在非严格模式下,在if或for语句块中声明的函数会被提升到当前作用域的顶部,可能会覆盖同名的函数或变量。严格模式下,如果在非函数代码块内声明函数,JavaScript会抛出一个语法错误。
function strictExample2() {
"use strict";
if(true) {
function myFunction() { // 在严格模式下,函数不能在非函数代码快中定义。这里会抛出一个语法错误
console.log('Hello, Strict Mode!');
}
myFunction();
}
}
strictExample2(); // 抛出语法错误:In strict mode code, functions can only be declared at top level or inside a block.
结论
通过严格模式,JavaScript增加了许多新特性,去除了大量的不规范、不守规矩的操作,帮助开发者编写更加简洁、高效、可靠的代码。在能够掌握严格模式的基础上,开发者可以避免一些常见的JavaScript陷阱,提高代码的可读性和可维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解javascript严格模式(Strict Mode) - Python技术站