严格模式是否可以移除而不产生副作用?

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

1
您可能希望将此网页添加到相关页面列表中:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode - Jason Sperske
请看这篇文章,希望能对你有所帮助:http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ - Nur Rony
2个回答

2

有一些情况可能会影响您的代码,但其中大多数都相当牵强。

  • When passing null or undefined as the this value (in non-strict mode this is converted to the global object, not an empty object):

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

    In strict mode, this would log "performs proper actions". However, this isn't the same in non-strict mode, where you'd get the failure message:

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

    It also has the same behaviour if you use null instead of undefined.

  • If your function relies on the this value not being coerced to an object -- in non-strict mode, this is implicitly coerced to an object. For example, values such as false, 'Hello World!', NaN, Infinity and 1 will be coerced to their object wrapper equivalents (as mentioned before, null and undefined have their own behaviour). Compare what happens in strict mode:

    'use strict';
    (function () { console.log(this); }).call(1); // 1
    

    ... with what happens in non-strict mode:

    (function () { console.log(this); }).call(1); // '[object Number]'
    
  • When relying on formal parameters and the arguments object not sharing their values on assignment:

    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);
    

    What you get is the following:

    strict: different
    strict: different
    strict: different
    strict: different
    non-strict: same
    non-strict: same
    non-strict: same
    non-strict: different
    
  • If you have been using eval and you call it directly, you'll find that variables and functions declared inside the eval call are leaked to the surrounding scope, instead of being in its own scope when in strict mode. For example, a retains its original value in strict mode:

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

    ... while in non-strict mode, it is assigned a new value:

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

    If you were relying on a new scope being created, this would be a breaking change to your code.

  • If you deliberately use the way that a ReferenceError is thrown if you attempt to assign to a variable that has not been defined yet, this will affect the way your code runs:

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

    The alert will not be shown in non-strict mode.

这些都可以在《附录C》中找到,该附录是ECMAScript 5.1规范的权威参考,其中详细说明了每种情况下会发生什么。虽然它不是很容易阅读,但了解特定的边缘情况及其行为方式可能会很有用。

1
在大多数情况下,严格模式只是限制了代码的行为,但是您不能假设去除严格模式永远不会改变行为。例如,在严格模式和正常模式下使用arguments数组是不同的。
示例:
function test(a) {
  "strict mode";
  a = 42;
  return arguments[0];
}

如果你使用 test(1337) 调用这个函数,它会返回 1337。但是如果你将它的严格模式移除,它会返回 42。
想要了解严格模式的完整列表,请参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接