Home > Article > Web Front-end > Understanding strict mode in javascript_javascript tips
1. What is strict mode
The JavaScript code we usually write generally runs in the normal mode. In addition to the normal running mode, ECMAscript 5 adds a second running mode: "strict mode". As you can tell from the name, this mode will make JavaScript run in a more strict environment.
Major browsers, including IE 10, already support it, and many large projects have begun to fully embrace it. (Many projects on github use strict mode)
2. Enable strict mode
Enable strict mode for entire script
Put a specific statement "use strict";
before all statements
Suppose there is a script reeoo.js, you can turn on strict mode like this:
"use strict"; var name = "Reeoo"; console.log(name);
There are natural pitfalls in this way of writing BUT. If we want to merge the code, I will now merge heigui.js:
heigui = "db";
Merge with reeoo.js. It is good for the two scripts to be executed separately, but an error will be reported when combined.
Uncaught ReferenceError: heigui is not defined(…)
The merging of a strict mode script and a non-strict mode script may cause the non-strict mode script code to report an error. It is recommended that the code be wrapped in an immediate execution function.
(function(){ "use strict"; var name = "reeoo"; })(); (function(){ heigui = "db"; })();
In this way, no errors will be reported after merging.
Enable strict mode for a function
To enable strict mode for a function, you must place the "use strict"; statement before all statements in the function body.
function strictFun() { // 函数级别严格模式语法 'use strict'; console.log('I am a strictmode function!'); } function normalFun() { console.log('I am a mormal function!'); }
Debugging strict mode in Chrome
I have this piece of code:
'use strict' name = "reeoo"; console.log(name)
Paste this code directly into the Chrome console and execute it. Under normal circumstances, an error should be reported, but no error is reported.
Obviously, in strict mode, it is illegal for variables to be declared without var, but why is no error reported?
What the hell is this? Does Chrome not support strict mode? What a joke. . .
After searching online, it turns out that Chrome's console code runs in eval, and you cannot use strict mode for the eval function (it may not be completely correct, but what exactly Chrome does is unknown), as shown below Explain that the eval function can use strict mode:
To properly report errors in strict mode in the Chrome browser, you need to wrap an immediate execution function outside the code, or other similar measures.
(function(){ 'use strict' name = "reeoo"; console.log(name) })()
That’s it
FireFox code scratch paper debugging strict mode
Chrome requires us to include a layer of closures to run strict mode. Since it is so troublesome, is there any other way to run strict mode code directly?
FireFox has a code scratch paper that can be run directly, the shortcut key SHIFT+F4
How strict is strict mode
Some important limitations in strict mode
1. Variable declaration
Using an undeclared variable is not allowed
"use strict"; name = "reeoo";
Error reporting (code draft paper, the same below)
Exception: ReferenceError: assignment to undeclared variable name
2. Modify the value of the read-only attribute
"use strict"; var testObj = Object.defineProperties({}, { prop1: { value: 10, writable: false // 一个只读的属性 }, prop2: { get: function () { } } }); testObj.prop1 = 20; //尝试改变prop1的值 testObj.prop2 = 30;//尝试改变prop2的值
An error will be reported in strict mode:
Uncaught TypeError: Cannot assign to read only property 'prop1' of #a87fdacec66f0909fc0757c19f2d2b1d
Non-strict mode means that the value cannot be assigned at most, and no error will be reported
3. Modify non-expandable attributes
behaves like adding a property to an object with the extensible property set to false.
"use strict"; var testObj = new Object(); Object.preventExtensions(testObj);//经过这个方法处理过的对象,不影响原有对象的删除,修改.但是无法添加新的属性成员了. testObj.name = "reeoo";
Strict mode error:
Uncaught TypeError: Can't add property name, object is not extensible
Non-strict mode will not report an error, but testObj will not be expanded.
4. Delete variables, functions or parameters
Remove properties with configurable attribute set to false.
"use strict"; var testvar = 15,testObj={}; function testFunc() {}; delete testvar; delete testFunc; Object.defineProperty(testObj, "testvar", { value: 10, configurable: false }); delete testObj.testvar;
报错:
Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
5、在一个对象文本中多次定义某个属性
严格模式下不允许一个属性有多个定义
"use strict"; var testObj = { prop1: 10, prop2: 15, prop1: 20 };
报错(node控制台)
Duplicate data property in object literal not allowed in strict mode
正常模式中后声明的重复的变量会覆盖前面声明的,而且不会报错。
注:这个问题在ECMAScript6中已被修复。
6、严格模式下不允许形参参数名称重复
"use strict"; function testFunc(param1, param1) { return 1; };
报错:
Uncaught SyntaxError: Duplicate parameter name not allowed in this context
7、无法使用标识符的未来保留字。严格模式下将保留标识符名称
一下标识符(ES6中依然没有实现的)在严格模式中是不能使用的,否则也会报错。
用了就是这个下场:
Uncaught SyntaxError: Unexpected strict mode reserved word
8、严格模式下不允许使用八进制数字参数和转义字符
"use strict"; var testoctal = 010; var testescape = \010;
报错:
Uncaught SyntaxError: Unexpected token ILLEGAL(…)
9、当this 的值为 null 或 undefined 时,该值不会转换为全局对象
比如:
"use strict"; function testFunc() { return this; } var testvar = testFunc();
在非严格模式下,testvar 的值为全局对象window,但在严格模式下,该值为 undefined。
10、字符串"eval"不能用作标识符(变量或函数名、参数名等)
"use strict"; var eval = "hehe";
Uncaught SyntaxError: Unexpected eval or arguments in strict mode
11、在严格模式下,函数声明无法嵌套在语句或块中。它们只能显示在顶级或直接显示在函数体中
"use strict"; var arr = [1, 2, 3, 4, 5]; var index = null; for (index in arr) { function myFunc() {}; }
node控制台:
SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
但是这个限制已经在ES6中被修复
12、严格模式下eval用法无效
如果在 eval 函数内声明变量,则不能在此函数外部使用该变量。
"use strict"; eval("var testvar = 10"); console.log(testvars);
Uncaught ReferenceError: testvar is not defined
13、严格模式下"arguments"用法无效
字符串”arguments”不能用作标识符(变量或函数名、参数名等)。
"use strict"; var arguments = 1;
Uncaught SyntaxError: Unexpected eval or arguments in strict mode
这个跟上面第10条的限制是差不多的。
14、函数内的 arguments,无法更改arguments 对象的成员的值
"use strict"; function testArgs(oneArg) { arguments[0] = 20; }
在非严格模式下,可以通过更改 arguments[0] 的值来更改 oneArg 参数的值,从而使 oneArg 和 arguments[0] 的值都为 20。在严格模式下,更改 arguments[0] 的值不会影响 oneArg 的值,因为 arguments 对象只是一个本地副本。
15、不允许使用arguments.callee
"use strict"; function my(testInt) { if (testInt-- == 0) return; arguments.callee(testInt--); } my(100);
用了的下场就是这样:
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
16、不允许使用with
"use strict"; with (Math){ x = cos(3); y = tan(7); }
Uncaught SyntaxError: Strict mode code may not include a with statement
为什么要使用严格模式
既然这种模式这么多限制,我为什么还要用呢?闲得蛋疼吗?当然8是,
JavaScript作为一门一开始用于浏览器的脚本语言,容错性非常好,即使有时候你的代码写的不标准,也不会报错,但这有时候会变成代码隐患。开启了严格模式之后,JavaScript的一些不合理的不严谨的语法都会得到控制,让你能够更严谨的书写JavaScript代码,成为一个更好的程序员。严格模式是ES5时代的产物,ES2015已经在普及的路上,是时候使用严格模式了!