我有一个 JavaScript 应用程序,我想知道是否通过删除所有“使用严格;” 程序中的语句,我会以某种方式改变它的行为。
据我了解,严格模式不允许某些东西,一旦应用程序完成开发,我可以将其删除而不会造成任何副作用。
还有这里提到的“this”变量的情况,但 Chrome 似乎直到现在还没有实现这种行为。
谢谢!
2 回答
在少数情况下,您的代码可能会受到影响,尽管其中大多数都是人为的:
当传递
null
orundefined
作为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!'
,NaN
和Infinity
之类的值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中找到,这是每种情况下发生的权威参考。虽然它不是很容易阅读,但了解特定的极端情况以及它们为何如此行事可能会很有用。
在大多数情况下,严格模式只是限制了代码可以做什么,但你不能假设删除严格模式永远不会改变行为。数组的使用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