3

我有一个 JavaScript 应用程序,我想知道是否通过删除所有“使用严格;” 程序中的语句,我会以某种方式改变它的行为。
据我了解,严格模式不允许某些东西,一旦应用程序完成开发,我可以将其删除而不会造成任何副作用。
还有这里提到的“this”变量的情况,但 Chrome 似乎直到现在还没有实现这种行为。
谢谢!

4

2 回答 2

2

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

  • 当传递nullorundefined作为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!',NaNInfinity之类的值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如果您在尝试分配给尚未定义的变量时故意使用抛出 a的方式,这将影响您的代码运行方式:

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

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

所有这些都可以在ECMAScript 5.1 规范的附件 C中找到,这是每种情况下发生的权威参考。虽然它不是很容易阅读,但了解特定的极端情况以及它们为何如此行事可能会很有用。

于 2013-11-03T06:17:48.763 回答
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

于 2013-11-03T06:20:58.773 回答