答案(请阅读下面的答案,各自的作者提供了宝贵的见解):
- “writable: false”会阻止分配新值,但是 Object.defineProperty 不是赋值操作,因此 忽略“可写”的值
- 属性属性 是继承的,因此属性在每个 子类/实例,直到一个子类(或子类的实例)将“可写”的值更改回 true 本身
问题:
有关属性“可写”描述符的 MDN 文档指出:
writable true if and only if the value associated with the property may be changed with an assignment operator. Defaults to 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)的原型(prototype)上重载。
但是,当尝试在子类(test4)的实例上重载该方法时,它会默默地失败。我本来希望它能像 test2 一样工作。当尝试重载 Parent 实例上的属性时,也会发生同样的情况。
同样的事情发生在 NodeJS 和 JSFiddle 中,并且在某些情况下,实例上的重载会引发有关属性只读性质的 TypeError。
您能否向我确认这是预期的行为?如果是这样,解释是什么?
最佳答案
是的,这是预期的行为。
it fails silently.
不完全是。或者:仅在草率模式下。如果你"use strict"
mode ,你会得到一个
Error { message: "Invalid assignment in strict mode", … }
在线 test4.answer = function() { return 0; };
it can be overloaded on the prototype of a subclass (test2), but not an instance of a subclass (test4)
这与实例与原型(prototype)无关。您没有注意到的是,您正在使用不同的方法来创建重载属性:
- 对属性 inherited and non-writable 的赋值失败
Object.defineProperty
调用只会创建一个新属性,除非该对象是不可扩展的
您可以对您的实例执行相同的操作:
Object.defineProperty(test4, "answer", {
value: function() { return 42; }
});
关于javascript - Javascript 可写描述符是否会阻止实例发生更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43096142/