简介
- StrictMode是ES5新增的功能,允许你讲程序、函数在Strict模式下运行。
- Strict Mode在JavaScript代码运行时自动实行更严格解析和错误处理的方法,当然会抛出更多的异常。
怎么用?
"use strict";
function doSomething() {
// this runs in strict mode
}
function doSomethingElse() {
// so does this
}
function strict() {
'use strict';
return "strict mode function!";
}
function notStrict() {
return "non strict function";
}
好处?
- 把某些javascript静默错误更改为引发错误,将提前暴露并消除这些错误。
- 修复了使JavaScript引擎难以执行优化的错误:
所以,严格模式代码有时比不严格模式的相同代码运行得更快。
- 禁止在未来版本的ecmascript中定义某些语法。
- 当采取相对“不安全”的操作(例如获取对全局对象的访问)时,它可以防止或抛出错误。
- 它禁用了 令人困惑或考虑不周 的功能。
- 编写“安全”的javascript变得更加容易。
坏处?
- Strict Mode禁掉了部分功能,这就导致,我们有一些写法必须要调整,有部分功能被认定不合理的都将无法使用。
- 这样,代码量也自然会多一点。
- 对开发人员的要求高了,要求会更高一点点。
思考
既然这么好,默认开启也挺好?为什么不默认开启呢?
- 从 好处 的说明看,这是纯粹有益的。而且,不支持的浏览器会自动忽略’use strict’的声明。
- 这里有个风险:如果一个页面使用的javascript依赖于 非Strict Mode的特性,那么,这个代码就会break掉。
- Strict Mode不是100%向后兼容。我们必须手动开启。
它做了什么?
- 变量使用前,必须先定义
‘use strict’;
x = 3.14; // will throw an error
‘use strict’;
x = {p1:10, p2:20}; // will throw an error
- 取消this值的强制转换
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};
xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined
原因是this指针只在age方法的函数内指向xiaoming,在函数内部定义的函数,this又指向undefined了!(在非strict模式下,它重新指向全局对象window!)
- 不允许删除变量,删除函数
‘use strict’;
var foo = "test";
function test(){}
delete foo; // will throw an error
delete test; // will throw an error
- 不允许function的参数重名
‘use strict’;
function x(p1, p1) {}; // will throw an error
- 不允许使用八进制数字
‘use strict’;
let x = 010; // will throw an error
- 不允许对 只读属性的变量 进行修改
‘use strict’;
let obj = {};
Object.defineProperty(obj, “x”, {value:0, writable:false});
obj.x = 3.14; //will throw an error
- 不允许删除 不写删除属性。非严格模式会失败,严格模式就报错
‘use strict’;
delete Object.prototype; // will throw an error
- 变量不能命名为 eval
‘use strict’;
let eval = 3.14; // will throw an error
- 变量不能命名为 arguments
‘use strict’;
let arguments = 3.14; // will throw an error
- 禁用with(){}
‘use strict’;
with (Math){x = cos(2)}; // will throw an error
- 不能使用arugment.caller和argument.callee。因此如果你要引用匿名函数,需要对匿名函数命名。
‘use strict’;
x = 3.14; // will throw an error