有一些情况可能会影响您的代码,但其中大多数都相当牵强。
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.
arguments
数组是不同的。function test(a) {
"strict mode";
a = 42;
return arguments[0];
}
test(1337)
调用这个函数,它会返回 1337。但是如果你将它的严格模式移除,它会返回 42。