可以在没有副作用的情况下删除严格模式吗

can strict mode be removed without side-effects

本文关键字:删除 模式 情况下 副作用      更新时间:2023-09-26

我有一个JavaScript应用程序,我想知道通过删除程序中的所有"use strict;"语句,我是否会以某种方式改变它的行为
据我所知,严格模式不允许一些东西,一旦应用程序完成开发,我就可以删除它而不会产生任何副作用
这里也提到了"this"变量的情况,但Chrome似乎到目前为止还没有实现这种行为
谢谢

在少数情况下,您的代码可能会受到影响,尽管其中大多数都是人为的:

  • 当传递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之类的值将被强制为它们的对象包装等价物(如前所述,nullundefined具有它们自己的行为(。比较严格模式下发生的情况:

    '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的方式,如果你试图分配给一个尚未定义的变量,这将影响你的代码运行方式:

    try {
        randomVariableThatHasntBeenDefined = 1;
    } catch (e) {
        alert('performs logic');
    }
    

    警报将不会在非严格模式下显示。

所有这些都可以在ECMAScript 5.1规范的附录C中找到,这是在每种情况下发生的事情的权威参考。虽然阅读起来并不容易,但理解特定的角落案例以及它们为什么会这样做是很有用的。

在大多数情况下,严格模式只是限制了代码的功能,但不能假设删除严格模式永远不会改变行为。CCD_ 21阵列的使用例如在严格模式和正常模式中是不同的。

示例:

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