资讯专栏INFORMATION COLUMN

JavaScript中的严格模式

wwolf / 2000人阅读

摘要:字符串不能用作标识符变量或函数名参数名等在严格模式下,函数声明无法嵌套在语句或块中。严格模式下用法无效如果在函数内声明变量,则不能在此函数外部使用该变量。在严格模式下,更改的值不会影响的值,因为对象只是一个本地副本。

本文同步自 我的博客,地址: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的控制台中执行,正常情况下应该报错,但是并没有报错,

很显然,严格模式下变量不适用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 #

非严格模式顶多就是值赋不上去而已,并不会报错

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 = 10;
 

报错:

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已经在普及的路上,是时候使用严格模式了!

参考

严格模式

严格模式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78629.html

相关文章

  • JavaScript面向对象中的严格模式

    摘要:开启严格模式设置对象是一个不可扩展的对象为对象新增属性张无忌在非严格模式下为不可扩展的对象添加新属性,结果是静默失败。 概述 严格模式是什么 严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。不支持严格模式的浏览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。严格模式可以与非严...

    bang590 评论0 收藏0
  • 那些年,前端学习之路的疑难杂症(一):严格模式与非严格模式

    摘要:反之亦然非严格合并严格看起来是非严格的。在普通的里面给一个拼写错误的变量名赋值会使全局对象新增一个属性并继续工作尽管后面可能出错在现在的中有可能。第三严格模式禁止删除声明变量。 文章整理自MSDN:https://developer.mozilla.org... 1.逐步使用严格模式 ECMAScript 5的严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个...

    zombieda 评论0 收藏0
  • 谈谈 JS 中的严格模式

    摘要:什么是严格模式严格模式是中引入的一种将更好的错误检查引入代码中的方法现在已经被大多浏览器实现顾名思义,这种模式使得在更严格的条件下运行因此在严格模式下我们的一些不严谨的写法将会导致程序抛出错误例如在严格模式下该行将会抛出错误在上面的代码中由 什么是严格模式? 严格模式 是 ECMAScript 5 中引入的一种将更好的错误检查引入代码中的方法, 现在已经被大多浏览器实现. 顾名思义,这...

    Meils 评论0 收藏0
  • JavaScript 严格模式下this的几种指向

    摘要:前言曾经被中的弄晕了,今天整理总结一下在严格模式下的几种指向。严格模式构造函数中的事件处理函数中的在严格模式下,在事件处理函数中,指向触发事件的目标对象。 前言 曾经被 JavaScript 中的 this 弄晕了,今天整理总结一下在严格模式下 this 的几种指向。 1. 全局作用域中的this 在严格模式下,在全局作用域中,this指向window对象 use stric...

    smallStone 评论0 收藏0
  • JavaScript之“use strict”

    摘要:在严格模式中,当运算符后跟随非法的标识符比如变量函数函数参数时,将会抛出一个语法错误异常在非严格模式中,这种表达式什么也没做,并返回。 JavaScript之use strict use strict是ECMAScript 5引入的一条指令。指令不是语句(但非常接近于语句)。usestrict指令和普通的语句之间有两个重要的区别: 它不包含任何语言的关键字,指令仅仅是一个包含一个特殊...

    econi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<