一、什么是严格模式
我们平时写的JavaScript代码一般都运行在正常模式中的,除了正常运行模式,ECMAscript 5添加了第二种运行模式:”严格模式”(strict mode)。看名字就知道,这种模式会让JavaScript在更严格的环境中运行。
包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱。(github上面好多项目都是用的严格模式)
二、启用严格模式
为整个脚本启用严格模式
在所有语句之前放一个特定语句 "use strict";
假设有一个脚本reeoo.js,可以这样开启严格模式:
"use strict"; var name = "Reeoo"; console.log(name);
BUT这种写法存在天然的坑,假如我们要做代码合并,我现在要把heigui.js:
heigui = "db";
和reeoo.js进行合并,本来两个脚本分开执行是好好的,合起来就会报错。
Uncaught ReferenceError: heigui is not defined(…)
一个严格模式的脚本和一个非严格模式的脚本合并可能会导致非严格模式的脚本代码报错,建议代码都包在一个立即执行函数里面。
(function(){ "use strict"; var name = "reeoo"; })(); (function(){ heigui = "db"; })();
这样合并之后就不会报错了。
为某个函数启用严格模式
要给某个函数开启严格模式,得把"use strict"; 声明放在函数体所有语句之前就行了。
function strictFun() { // 函数级别严格模式语法 'use strict'; console.log('I am a strictmode function!'); } function normalFun() { console.log('I am a mormal function!'); }
Chrome中调试严格模式
我有这么一段代码:
'use strict' name = "reeoo"; console.log(name)
把这段代码直接粘贴到Chrome的控制台中执行,正常情况下应该报错,但是并没有报错,
很显然,严格模式下变量不适用var声明是不合法的,但是为什么没有报错?
这是什么鬼,难道Chrome不支持严格模式?开什么玩笑。。。
网上搜了一下,原来Chrome的控制台的代码是运行在eval之中的,你没法对eval函数使用严格模式(应该也不完全对,但是具体Chrome做了什么,不得而知),下图说明eval函数可以使用严格模式:
要想在Chrome浏览器中对严格模式正常报错,需要在代码外层套一个立即执行函数,或者其它类似的措施。
(function(){ 'use strict' name = "reeoo"; console.log(name) })()
这样就可以了
FireFox代码草稿纸调试严格模式
Chrome非要我们包一层闭包才能跑严格模式,既然这么麻烦,有没有别的方式可以直接跑严格模式的代码呢?
FireFox有一个代码草稿纸可以直接跑,快捷键SHIFT+F4
严格模式到底有多严格
严格模式中一些重要的限制
1、变量声明
不允许使用一个没有声明的变量
"use strict"; name = "reeoo";
报错(代码草稿纸,下同)
Exception: ReferenceError: assignment to undeclared variable name
2、修改只读属性的值
"use strict"; var testObj = Object.defineProperties({}, { prop1: { value: 10, writable: false // 一个只读的属性 }, prop2: { get: function () { } } }); testObj.prop1 = 20; //尝试改变prop1的值 testObj.prop2 = 30;//尝试改变prop2的值
严格模式下会报错:
Uncaught TypeError: Cannot assign to read only property 'prop1' of #<Object>
非严格模式顶多就是值赋不上去而已,并不会报错
3、修改不可扩展的属性
表现为将属性添加到 extensible 属性设置为 false 的对象。
"use strict"; var testObj = new Object(); Object.preventExtensions(testObj);//经过这个方法处理过的对象,不影响原有对象的删除,修改.但是无法添加新的属性成员了. testObj.name = "reeoo";
严格模式报错:
Uncaught TypeError: Can't add property name, object is not extensible
非严格模式不会报错,但是testObj也不会被扩展。
4、删除变量、函数或参数
删除 configurable 特性设置为 false 的属性。