On the MDN strict mode reference page it says
Any assignment that silently fails in normal code (assignment to a non-writable property, assignment to a getter-only property, assignment to a new property on a non-extensible object) will throw in strict mode
So, using their example, doing something like the following throws a TypeError
"use strict";
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // throws a TypeError
However I ran into an example where it seems 'use strict' is being a little overzealous about this rule. Here is my setup
definelol.js
Object.defineProperty(Object.prototype, 'lol', {
value: 'wat'
})
setlol.js
'use strict';
console.log('here 0');
var sugar = { lol: '123' }
console.log('here 1');
var verbose = {};
verbose.lol = '123';
console.log('here 2');
console.log('sugar.lol:', sugar.lol);
console.log('verbose.lol:', verbose.lol);
console.log('Object.prototype.lol:', Object.prototype.lol);
app.js
require('./definelol.js');
require('./setlol.js');
running node app.js
gives
here 0
here 1
/pathto/setlol.js:10
verbose.lol = '123';
^
TypeError: Cannot assign to read only property 'lol' of #<Object>
at Object.<anonymous> (/pathto/setlol.js:10:13)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/pathto/app.js:2:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
There are a couple of interesting things that are interesting about this output. First is that we are not trying to set the lol
property on Object.prototype
we are trying to set the lol
property of verbose
. To prove this I changed definelol.js
to be
Object.defineProperty(Object.prototype, 'lol', {
writable: true,
value: 'wat'
})
Now, running node app.js
gives
here 0
here 1
here 2
sugar.lol: 123
verbose.lol: 123
Object.prototype.lol: wat
The second thing that was interesting was that the original program failed on verbose.lol = '123'
but was perfectly happy creating sugar
and setting its lol
to 123. I don't understand this because it seems that the way we created sugar
should simply be syntactic sugar for the way we created verbose