严格模式是什么
ECMAScript 5的严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地 脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
严格模式对正常的 JavaScript语义做了一些更改。
- 严格模式通过抛出错误来消除了一些原有静默错误。
- 严格模式修复了一些导致JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
- 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
调用严格模式
严格模式可以应用到整个脚本或个别函数中。
- 为脚本开启严格模式
为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句 "use strict"; (或 'use strict';)
(function(){
"use strict";
var v = "Hi! I'm a strict mode script!";
})();
- 为函数开启严格模式
function strict() {
// 函数级别严格模式语法
'use strict';
function nested() {
return "And so am I!";
}
return "Hi! I'm a strict mode function! " + nested();
}
function notStrict() {
return "I'm not strict.";
}
严格模式中的变化
- 不允许使用未声明的变量 (严格模式中意外创建全局变量被抛出错误替代)
(function(){
"use strict";
x = 3.14; // Uncaught ReferenceError: x is not defined
})();
- 不允许删除变量或对象(严格模式禁止删除声明变量)
(function(){
"use strict";
var x = 3.14;
delete x; //Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
})();
- 不允许删除函数
(function(){
"use strict";
function x(p1, p2) {};
delete x; //Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
})();
- 不允许变量重名(严格模式要求函数的参数名唯一)
(function(){
"use strict";
function x(p1,p1){}; //Uncaught SyntaxError: Duplicate parameter name not allowed in this context
})();
- 不允许使用八进制(严格模式禁止八进制数字语法)
(function(){
"use strict";
var x = 010; //Uncaught SyntaxError: Octal literals are not allowed in strict mode.
})();
- 不允许使用转义字符
(function(){
"use strict";
var x = \010; //Uncaught SyntaxError: Invalid or unexpected token
})();
- 不允许对不可写属性赋值
(function(){
"use strict";
//给不可写属性赋值
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});
obj.x = 3.14; //Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
})();
- 不允许对一个使用getter方法读取的属性进行赋值 (只读属性赋值)
(function(){
"use strict";
//给只读属性赋值
var obj = {get x() {return 0} };
obj.x = 3.14; //Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
})();
- 不允许给不可扩展对象的新属性赋值
(function(){
"use strict";
// 给不可扩展对象的新属性赋值
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; //Uncaught TypeError: Cannot add property newProp, object is not extensible
})();
- 不允许删除一个不允许删除的属性
(function(){
"use strict";
delete Object.prototype; //Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
})();
- 变量名不能使用 "eval" 字符串
(function(){
"use strict";
var eval = 3.14; //Uncaught SyntaxError: Unexpected eval or arguments in strict mode
})();
- 变量名不能使用 "arguments" 字符串
(function(){
"use strict";
var arguments = 3.14; //Uncaught SyntaxError: Unexpected eval or arguments in strict mode
})();
//名称 eval 和 arguments 不能通过程序语法被绑定(be bound)或赋值. 以下的所有尝试将引起语法错误:
(function(){
"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");
})();
- 不允许使用以下这种语句(严格模式禁用 with)
(function(){
"use strict";
with (Math){x = cos(2)}; //Uncaught SyntaxError: Strict mode code may not include a with statement
})();
(function(){
"use strict";
var x = 17;
with (obj) { // !!! 语法错误
// 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?
// 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。
x;
}
})();
- 由于一些安全原因,在作用域 eval() 创建的变量不能被调用
(function(){
"use strict";
eval("var x = 2");
console.log(x); //Uncaught ReferenceError: x is not defined
})();
- 禁止this关键字指向全局对象
function f(){
return !this;
}
// 返回false,因为"this"指向全局对象,"!this"就是false
function f(){
"use strict";
return !this;
}
// 返回true,因为严格模式下,this的值为undefined,所以"!this"为true。
//使用构造函数时,如果忘了加new,this不再指向全局对象,而是报错。
function f(){
"use strict";
this.a = 1;
};
f();// Uncaught TypeError: Cannot set property 'a' of undefined
- 保留关键字
严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, static和yield。在严格模式下,你不能再用这些名字作为变量名或者形参名。
(function(){
"use strict";
var implements; //Uncaught SyntaxError: Unexpected strict mode reserved word
})();
- ECMAScript 6中的严格模式禁止设置primitive值的属性
(function() {
"use strict";
false.true = ""; //Uncaught TypeError: Cannot create property 'true' on boolean 'false'
(14).sailing = "home"; //Uncaught TypeError: Cannot create property 'sailing' on number '14'
"with".you = "far away"; //Uncaught TypeError: Cannot create property 'you' on string 'with'
})();
- 严格模式下,参数的值不会随 arguments 对象的值的改变而变化
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
- 不再支持 arguments.callee
在严格模式下,arguments.callee 是一个不可删除属性,而且赋值和读取时都会抛出异常。
(function(){
"use strict";
var f = function() { return arguments.callee; };
f(); //Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
})();
- 不支持fun.caller和fun.arguments
如果fun在严格模式下,那么fun.caller和fun.arguments都是不可删除的属性而且在存值、取值时都会报错。
function restricted() {
"use strict";
restricted.caller; //Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
restricted.arguments; // 抛出类型错误
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
More
MDN严格模式
developer.mozilla.org/zh-CN/docs/…
Javascript 严格模式详解
www.ruanyifeng.com/blog/2013/0…
JavaScript 严格模式(use strict)
www.runoob.com/js/js-stric…