Reputation: 2797
I have a JavaScript application and I would like to know if by removing all the "use strict;" statements in the program, I would be changing its behaviour in some way.
As far as I understand, strict mode does not allow some stuff and once the application has finished development, I can remove it without causing any side-effects.
There is also the case of the 'this' variable mentioned here but Chrome does not seem to have implemented this behaviour till now.
Thanks!
Upvotes: 3
Views: 163
Reputation: 16020
There are a few cases where your code may be affected, though most of them are rather contrived:
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.
All of these can be found in Annex C of the ECMAScript 5.1 Specification, which is the authoritative reference for what happens in each of these cases. While it isn't exactly easy reading, it can be useful to understand particular corner cases and why they behave as they do.
Upvotes: 2
Reputation: 700372
In most cases strict mode just limits what the code can do, but you can't assume that removing strict mode never changes the behaviour. The use of the arguments
array is for example different in strict mode and normal mode.
Example:
function test(a) {
"strict mode";
a = 42;
return arguments[0];
}
If you call this function with test (1337)
it will return 1337, but if you remove the strict mode from it, it would instead return 42.
For a comprehensive list of what the strict mode does: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
Upvotes: 1