MDN strict mode help page says
Any assignment that, without speculative failure in the normal code (assignment to an unprivileged property, assignment to a property only for a getter, assignment to a new property on a non-extensible object) will cause 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;
However, I came across an example where, it seems, "use strict" overestimates this rule a bit. 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
There are a few interesting things that are interesting in this release. First, we are not trying to set the lol property to Object.prototype , we are trying to set the lol verbose property. To prove this, I changed definelol.js to
Object.defineProperty(Object.prototype, 'lol', { writable: true, value: 'wat' })
Now starting node app.js gives
here 0 here 1 here 2 sugar.lol: 123 verbose.lol: 123 Object.prototype.lol: wat
The second interesting thing was that the original program did not work on verbose.lol = '123' , but was quite happy to create sugar and set its lol to 123. I do not understand this, because it seems that we created sugar should be just syntactic sugar for how we created verbose