JavaScript中的严厉形式

本文同步自 我的博客,地点:http://reeoo.me/archives/strictmode.html

什么是严厉形式

我们日常平凡写的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的掌握台中实行,一般情况下应当报错,然则并没有报错,

《JavaScript中的严厉形式》

很显然,严厉形式下变量不实用var声明是不合法的,然则为何没有报错?

这是什么鬼,岂非Chrome不支撑严厉形式?开什么打趣。。。

网上搜了一下,本来Chrome的掌握台的代码是运转在eval当中的,你没法对eval函数运用严厉形式(应当也不完全对,然则详细Chrome做了什么,不得而知),下图申明eval函数能够运用严厉形式:

《JavaScript中的严厉形式》

要想在Chrome浏览器中对严厉形式一般报错,需要在代码外层套一个马上实行函数,或许别的相似的步伐。

(function(){
    'use strict'
    name = "reeoo";
    console.log(name) 
})()

如许就能够了

FireFox代码草稿纸调试严厉形式

Chrome非要我们包一层闭包才能跑严厉形式,既然这么贫苦,有无别的体式格局能够直接跑严厉形式的代码呢?

FireFox有一个代码草稿纸能够直接跑,快捷键SHIFT+F4

《JavaScript中的严厉形式》

严厉形式到底有多严厉

严厉形式中一些主要的限定

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 的属性。

"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
implements
interface
package
private
protected
public
static
yield

8. 严厉形式下不许可运用八进制数字参数和转义字符

"use strict";
var testoctal = 010;
var testescape = \010;
 

报错:

Uncaught SyntaxError: Unexpected token ILLEGAL(…)

9. 当 this 的值为 nullundefined 时,该值不会转换为全局对象

比方:

"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 参数的值,从而使 oneArgarguments[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已在提高的路上,是时刻运用严厉形式了!

参考

  1. 严厉形式

  2. 严厉形式

    原文作者:ireeoo
    原文地址: https://segmentfault.com/a/1190000004394829
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞