js严格模式详解
什么是严格模式
严格模式"use strict";是ES5新增的语法,在不⽀持严格模式的浏览器中,这⾏代码仅会被识别为⼀个“字⾯量表达式语句”,⽽在⽀持严格模式的浏览器中,这⾏代码表⽰在对应作⽤域内开启严格模式。
为什么要使⽤严格模式
启⽤严格模式后后,JavaScript引擎会对代码进⾏更加严格的评估,对之前较为宽松的、静默处理的、难以优化的代码进⾏语法检查,以便于开发⼈员在编写代码的过程中实时分析,并显⽰语法和代码的质量问题。
在何处使⽤"use strict";
在显式使⽤式"use strict";时,由于"use strict";可以作⽤到所以在位置的整个作⽤域,所以式"use strict";应⽤在某个作⽤域开始位置即可,即:
1.全局代码的开始处加⼊
2.在eval代码开始处加⼊
3.在函数声明语句开始处加⼊
4.在new Function()所传⼊的函数体开始处加⼊
除此之外,还有⼀些情况下默认使⽤严格模式,如:
1.ES6模块中
2.ES6的类声明和类表达式的整个声明中(包含extends关键字后边的表达式)
3.在引擎或宿主的运⾏参数中指定,如node --use_strict
语法限制
在严格模式中,有7种语法被禁⽤。
在对象字⾯量声明中存在相同的属性名
此语法限制是在ES5中规定的,但ES6就取消了,所以最后⼀个声明项总是有效的,只在不⽀持ES6的浏览器中会报错
"use strict";
var obj = {
name: "Lily",
name: "Wango"
}
// IE11中报错: strict 模式下不允许⼀个属性有多个定义
在函数声明中,参数具有相同标识符
在⾮严格模式中,总是后⼀个同名参数⽣效(前⼀个被覆盖)
"use strict";
function foo(a, a, b) {}
// SyntaxError: Duplicate parameter name not allowed in this context
// ⾮严格模式
function foo(a, a, c, b, b, c) {
console.log(a + c);
}
// 参数的个数不会因为重名⽽改变,写了多少就是多少
console.log(foo.length);
// 6
// 重复变量都是最后⼀个声明⽣效,覆盖了前者
foo(1, 2, 3, 4, 5, 6);
// 8
// 在这⾥传三个实参,第⼆个c的值为undefined,2 + undefined得到NaN
foo(1, 2, 3);
/
/ NaN
不能声明、重写或删除eval和arguments
"use strict";
// 不能重新赋值,不能重新声明(变量声明和函数声明都不允许)
eval = function() {};
// SyntaxError: Unexpected eval or arguments in strict mode
var arguments;
// SyntaxError: Unexpected eval or arguments in strict mode
function arguments(){}
// SyntaxError: Unexpected eval or arguments in strict mode
// 不能作为形参标识符
function foo(eval) {}
// SyntaxError: Unexpected eval or arguments in strict mode
// 不能作为catch⼦句的异常对象名
try{} catch(arguments) {}
// SyntaxError: Unexpected eval or arguments in strict mode
// 不能删除
delete eval;
// Delete of an unqualified identifier in strict mode.
delete arguments;
// Delete of an unqualified identifier in strict mode.
⽽在⾮严格模式中以上语法都是有效的
⽤0前缀声明⼋进制字⾯量
"use strict";
var num = 012;
// SyntaxError: Octal literals are not allowed in strict mode.
console.log(num);
在⾮严格模式下以上代码输出10
⽤delete删除显式声明的标识符、名称或具名函数
"use strict";
var a;
delete a;
// Delete of an unqualified identifier in strict mode.
function foo(){}
delete foo;
// Delete of an unqualified identifier in strict mode.
function foo(a) {
delete a;
// Delete of an unqualified identifier in strict mode.
}
try{}catch(err){ delete err}
// Delete of an unqualified identifier in strict mode.
在⾮严格模式中,以上操作⽆效,但不会抛出错误
使⽤保留字
"use strict";
function interface() {}
// SyntaxError: Unexpected strict mode reserved word
包含with语句
在严格模式中,with直接被禁⽌了
"use strict";
with(window) {}
// SyntaxError: Strict mode code may not include a with statement
执⾏限制
对未声明的标识符赋值
在⾮严格模式中,对未声明的标识符赋值时,会在全局对象上创建该标识符并完成运算,⽽在严格模式下,这种⾏为将导致ReferenceError。
"use strict";
a = 10;
// ReferenceError: a is not defined
// ⾮严格模式
a = 10;
console.log(window.a);
// 10
对不可操作的内容进⾏操作
"use strict";
var obj = {
name: 'Wango'
}
Object.preventExtensions(obj);
obj.age = 24;
// TypeError: Cannot add property age, object is not extensible
Object.seal(obj);
delete obj.name;
// TypeError: Cannot delete property 'name' of #<Object>
delete Function.prototype;
// TypeError: Cannot delete property 'prototype' of function Function() { [native code] }
Object.defineProperty(obj, 'age', {
writable: false,
value: 24
});
obj.age = 25;
// TypeError: Cannot assign to read only property 'age' of object '#<Object>'
⾮严格模式下忽略、⽆效、静默处理
访问arguments.callee或函数的caller属性
"use strict";
function foo() {
console.log(foo.caller);
// TypeError: 'caller', 'callee', and 'arguments' properties
// may not be accessed on strict mode functions or the
/
/ arguments objects for calls to them
}
foo();
造成这个问题的是.语法存取属性,⽽不是属性本⾝,所以以下代码在严格模式下也是能执⾏的:
"use strict";
function foo() {
console.log('callee' in arguments);
// true
console.log('caller' in foo);
// true
}
foo();
arguments与参数的不同表现
在⾮严格模式中,arguments的数据和参数的数据是相互绑定的,可以看作是指向同⼀⽚内存空间,⼀个改变,另⼀个会⼀起改变function foo(a, b) {
console.log(a, b);
// A B
arguments[0] = 10;
console.log(a, b);
// 10 B
b = 20;
console.log(arguments);
// [10, 20]
}
foo('A', 'B');
⽽在严格模式中,arguments与参数的修改将不再相互影响
"use strict";
function foo(a, b) {
console.log(a, b);
// A B
arguments[0] = 10;
console.log(a, b);
// A B
b = 20;
console.log(arguments);
// [10, B]
}
foo('A', 'B');
严格模式的范围
除⾮在启动JavaScript引擎时将其设置为严格模式,或者通过ES6模块加载整个系统,否在指定⼀个有限的严格模式。
"use strict";只能⽤于作⽤域的起始位置,在此代码前有任何代码都会导致严格模式失效,就算仅有⼀个;。
// 严格模式失效
;"use strict";
var eval;
在函数作⽤域中,严格模式能作⽤于函数中的代码,同样也能作⽤于函数本⾝
js arguments
function eval() {
// SyntaxError: Unexpected eval or arguments in strict mode
"use strict";
}
// 严格模式外的代码不受影响
var arguments;
参考资料:
《JavaScript语⾔精髓与编程实践(第3版)》(周爱民/著)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。