可以删除严格模式,没有副作用

时间:2013-11-03 05:51:21

标签: javascript

我有一个JavaScript应用程序,我想知道是否通过删除所有“use strict;”在程序中的陈述,我会以某种方式改变它的行为。
据我所知,严格模式不允许一些东西,一旦应用程序完成开发,我可以删除它而不会产生任何副作用。
还有一个'this'变量提到here的情况,但Chrome似乎直到现在才实现此行为。
谢谢!

2 个答案:

答案 0 :(得分:2)

在某些情况下,您的代码可能会受到影响,但大多数代码都是相当人为的:

  • nullundefined作为this值传递时(在非严格模式下,它将转换为全局对象,而不是空对象):

    'use strict';
    (function () {
        if (!this) console.log('performs proper actions');
        else console.log('fail! oops...');
    }).call(undefined); // 'performs proper actions'
    

    在严格模式下,这会记录"performs proper actions"。但是,在非严格模式下,这是不一样的,您将收到失败消息:

    (function () {
        if (!this) console.log('performs proper actions');
        else console.log('fail! oops...');
    }).call(undefined); // 'fail! oops...'
    

    如果您使用null代替undefined,它也会有相同的行为。

  • 如果您的函数依赖于this值未被强制转换为对象 - 在非严格模式下,this将被隐式强制转换为对象。例如,false'Hello World!'NaNInfinity1等值将被强制转换为其对象包装器(如前所述,{{ 1}}和null有自己的行为)。比较严格模式下发生的事情:

    undefined

    ...以非严格模式发生的事情:

    'use strict';
    (function () { console.log(this); }).call(1); // 1
    
  • 依赖形式参数且(function () { console.log(this); }).call(1); // '[object Number]' 对象在分配时不共享其值:

    arguments

    您得到的是以下内容:

    function strict(a, b, c) {
        'use strict';
        var a = 1;
        var b = 2;
        var c = 3;
        var d = 4;
        console.log('strict: ' + (arguments[0] === a ? 'same' : 'different')); // different
        console.log('strict: ' + (arguments[1] === b ? 'same' : 'different')); // different
        console.log('strict: ' + (arguments[2] === c ? 'same' : 'different')); // different
        console.log('strict: ' + (arguments[3] === d ? 'same' : 'different')); // of course they're different; by design
    }
    
    function notStrict(a, b, c) {
        var a = 1;
        var b = 2;
        var c = 3;
        var d = 4;
        console.log('non-strict: ' + (arguments[0] === a ? 'same' : 'different')); // same
        console.log('non-strict: ' + (arguments[1] === b ? 'same' : 'different')); // same
        console.log('non-strict: ' + (arguments[2] === c ? 'same' : 'different')); // same
        console.log('non-strict: ' + (arguments[3] === d ? 'same' : 'different')); // of course they're different; by design
    }
    
    strict(0, 1, 2, 3);
    notStrict(0, 1, 2, 3);
    
  • 如果您一直在使用strict: different strict: different strict: different strict: different non-strict: same non-strict: same non-strict: same non-strict: different 并直接调用它,您会发现在eval调用中声明的变量和函数会泄漏到周围的范围,而不是在在严格模式下它自己的范围。例如,eval在严格模式下保留其原始值:

    a

    ...在非严格模式下,会为其分配一个新值:

    'use strict';
    var a = 42;
    eval('var a = -Infinity;');
    console.log(a); // 42
    

    如果您依赖于正在创建的新范围,这将对您的代码进行重大更改。

  • 如果您故意使用如果您尝试分配尚未定义的变量而引发var a = 42; eval('var a = -Infinity;'); console.log(a); // -Infinity 的方式,则会影响代码的运行方式:

    ReferenceError

    警报不会以非严格模式显示。

所有这些都可以在Annex CECMAScript 5.1 Specification中找到,这是对这些案例中发生的事情的权威参考。虽然阅读起来并不容易,但了解特定的角落案例及其行为方式可能非常有用。

答案 1 :(得分:1)

在大多数情况下,严格模式仅限制代码可以执行的操作,但您不能假设删除严格模式永远不会更改行为。例如,arguments数组在严格模式和普通模式下的使用是不同的。

示例:

function test(a) {
  "strict mode";
  a = 42;
  return arguments[0];
}

如果您使用test (1337)调用此函数,它将返回1337,但如果您从中删除严格模式,它将返回42。

有关严格模式的完整列表:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode