tle*_*eef 6 javascript use-strict node.js defineproperty
在正常代码中静默失败的任何赋值(赋值给不可写属性,赋值给getter-only属性,赋值给非可扩展对象上的新属性)将以严格模式抛出
因此,使用他们的示例,执行类似下面的操作会引发TypeError
"use strict";
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // throws a TypeError
Run Code Online (Sandbox Code Playgroud)
然而,我遇到了一个例子,似乎"使用严格"对这条规则有点过分热心.这是我的设置
definelol.js
Object.defineProperty(Object.prototype, 'lol', {
value: 'wat'
})
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
app.js
require('./definelol.js');
require('./setlol.js');
Run Code Online (Sandbox Code Playgroud)
跑步node app.js给
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)
Run Code Online (Sandbox Code Playgroud)
关于这个输出,有一些有趣的事情是有趣的.首先,我们没有尝试设置lol属性,Object.prototype我们正在尝试设置lol属性verbose.为了证明这一点,我改变definelol.js了
Object.defineProperty(Object.prototype, 'lol', {
writable: true,
value: 'wat'
})
Run Code Online (Sandbox Code Playgroud)
现在,跑步node app.js给了
here 0
here 1
here 2
sugar.lol: 123
verbose.lol: 123
Object.prototype.lol: wat
Run Code Online (Sandbox Code Playgroud)
第二件有趣的事情是原始程序失败了,verbose.lol = '123'但非常高兴创建sugar并将其设置lol为123.我不明白这一点,因为我们创建的方式似乎sugar应该只是我们创建的方式的语法糖verbose
当赋值发生在严格模式代码中时,其 LeftHandSide 不得计算为无法解析的引用。如果确实如此,则在赋值时会引发 ReferenceError 异常。LeftHandSide 也不能是对具有属性值 {[[Writable]]:false} 的数据属性、具有属性值 {[[Set]]:undefined} 的访问器属性的引用,也不能是对不存在的属性的引用。其 [[Extensible]] 内部属性值为 false 的对象的属性。在这些情况下,会引发 TypeError 异常。
在示例代码中,表达式的左侧=实际上是对“可写”标志设置为 的数据属性的引用false。
现在我有点同情它不应该适用于继承的属性的观点,但我可以看到可能存在强烈的反驳。对象字面量允许将属性创建为新“糖”对象的“自己”属性,这当然看起来很奇怪。
编辑- 为了清楚起见,这里的问题是对对象属性的分配始终是分配给对象的“自己”属性。赋值不会影响继承链上的属性。因此,提出的问题涉及以下明显的矛盾:如果对象原型中的某个属性设置了“可写”标志以阻止在现有false对象上对该属性名称进行赋值,那么为什么在评估过程中对该属性的赋值会成功对象字面量?
这可能有一个很好的理由,也可能是一个错误。V8 和 Firefox 运行时当前的名称(我猜是猴子)都以相同的方式运行。