【发布时间】:2016-05-12 16:28:09
【问题描述】:
答案(请阅读下面的答案,他们各自的作者提供了宝贵的见解):
- "writable: false" 阻止分配新值,但是 Object.defineProperty 不是赋值操作,因此 忽略“可写”的值
- 属性属性 是继承的,因此一个属性将保持不可写 子类/实例,直到一个子类(或子类的实例)将“可写”的值更改回为真
问题:
关于属性“可写”描述符的 MDN 文档指出:
可写 当且仅当与属性关联的值可以使用赋值运算符更改时才为真。 默认为 false。
官方的 ECMA-262 第 6 版或多或少地声明了相同的内容。 含义很清楚,但据我了解,它仅限于原始属性(即该特定对象上的属性)
但是,请考虑以下示例 (JSFiddle):
//works as expected, overloading complete
var Parent = function() {};
Object.defineProperty(Parent.prototype, "answer", {
value: function() { return 42; }
});
var Child = function() {};
Child.prototype = Object.create(Parent.prototype, {
answer: {
value: function() { return 0; }
}
});
var test1 = new Parent();
console.log(test1.answer()); //42
var test2 = new Child();
console.log(test2.answer()); //0
//does not work as expected
var Parent2 = function() {};
Object.defineProperty(Parent2.prototype, "answer", {
value: function() { return 42; }
});
var Child2 = function() {};
Child2.prototype = Object.create(Parent2.prototype);
test3 = new Parent2();
console.log(test3.answer()); //42
test4 = new Child2();
test4.answer = function() { return 0; };
console.log(test4.answer()); //42
按照这个例子,我们看到,虽然该属性不可写,但它可以在子类 (test2) 的原型上重载,正如我所期望的那样。
但是,当尝试在子类 (test4) 的实例上重载方法时,它会静默失败。我原以为它可以像 test2 一样工作。尝试重载 Parent 实例上的属性时也会发生同样的情况。
同样的事情发生在 NodeJS 和 JSFiddle 中,并且在某些情况下,实例上的重载会引发关于属性只读性质的 TypeError。
您能否向我确认这是预期的行为?如果有,说明什么?
【问题讨论】:
-
你确实意识到你有一个错字,对吧?回答者
-
谢谢。此处显示的示例不是我的原始代码,而是为清楚起见为该问题制作的示例。纠正错字后,我现在意识到它不能正确地证明手头的问题。我相应地更新了帖子
-
我一直在想这个问题,你给了我做研究所需的推动力。
-
@JuanMendes 在这里也一样! @Gilgalas 在您的答案中,第一个答案的表述不正确。
child.prototype上的defineProperties是可能的,因为child.prototype没有answer的描述符。该描述符在child.prototype.constructor.prototype中定义。所以它并没有忽略它,它只是还不存在:-)child.prototype.constructor.prototype等于parent.prototype
标签: javascript node.js inheritance writable