我有一些代码在原型上定义了一个getter(但没有setter,如果相关的话)。返回的值在99.99%的情况下是正确的;但是,目标是将属性设置为评估特定对象的不同值。
foo = {}
Object.defineProperty(foo, "bar", {
// only returns odd die sides
get: function () { return (Math.random() * 6) | 1; }
});
x = Object.create(foo);
x.bar // => eg. 5
x.bar = 4 // by fair dice roll
x.bar // nope => eg. 3
如何为现有对象x重写属性,使其可分配(例如,具有默认属性行为)?
附录:虽然可以在x上定义新属性(值或获取/设置),但我正在寻找是否有办法阻止[原型]中属性的行为并将“条形”转回普通/广告-hoc特定实例的属性。
在Object.defineProperty
上使用x
:
var foo = {}
Object.defineProperty(foo, "bar", {
// only returns odd die sides
get: function () { return (Math.random() * 6) | 1; }
});
var x = Object.create(foo);
display(x.bar); // E.g. 5
(function() {
var bar;
var proto = Object.getPrototypeOf(x); // Or just use foo
Object.defineProperty(x, "bar", {
get: function () { return typeof bar !== "undefined" ? bar : proto.bar; },
set: function(value) { bar = value; }
});
})();
display(x.bar); // Still odd
x.bar = 4; // By fair dice roll
display(x.bar); // Shows 4
function display(msg) {
document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>");
}
我正在寻找是否有办法在[prototype]中停止属性的行为并将“bar”变回普通/ ad-hoc属性。
好的,这有点不同,但仍然使用Object.defineProperty
:
var foo = {}
Object.defineProperty(foo, "bar", {
// only returns odd die sides
get: function () { return (Math.random() * 6) | 1; }
});
var x = Object.create(foo);
display(x.bar); // E.g. 5
Object.defineProperty(x, "bar", {
value: undefined,
writable: true,
enumerable: true // Or leave off if you want it non-enumerable
});
display(x.bar); // undefined
x.bar = 4; // By fair dice roll
display(x.bar); // Shows 4
function display(msg) {
document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>");
}
作为T.J.克劳德说,再次使用defineProperty
就可以了。您可以考虑以下变体,其中setter本身会覆盖该属性:
Foo = function () {}
Foo.prototype = {
// computes, but only knows odd die sides
get bar() {
console.log("getter invoked")
return (Math.random() * 6) | 1
},
// fix it
set bar(value) {
console.log("setter invoked")
Object.defineProperty(
this, 'bar',
{writable: true, enumerable: true, configurable: true}
)
this.bar = value
}
}
var x = new Foo
console.log(x.bar) // => eg. 5
x.bar = 4 // by fair dice roll
console.log(x.bar) // => 4
x.bar = 2 // no setter, no getter
console.log(x.bar)
我希望你能原谅我用稍微不同的语法重写。它并没有改变任何东西。当我来到这篇文章时,我实际上只是在寻找一种方法来覆盖继承的getter
。