考虑这样的模式,我们想为属性定义一个很好的 getter/setter 接口以隐藏一些内部验证:
var validThings = {
'pretty name a': 3293293,
'pretty name b': 8275850,
'pretty name c': 2983855
};
function Constructor() {
var internalThing = {
name: 'pretty name a',
id: '3293293'
};
Object.defineProperty(this, 'thing', {
get: function() { return internalThing.name; },
set: function(val) {
var id = validThings[val];
if (id) internalThing = { name: val, id: id };
}
});
}
这让我们不必担心 id,因此我们可以像这样设置“事物”:
var constructoid = new Constructor();
constructoid.thing = 'pretty name b';
constructoid.thing; // 'pretty name b';
当然,它会阻止我们将其设置为无效值:
constructoid.thing = 'pretty name d';
constructoid.thing; // 'pretty name b';
但假设我们也希望能够从对象外部访问 ID。最自然的接口是作为事物的属性
constructoid.thing.id
但是,当“事物”本身就是一个 getter/setter 时,如何定义这样的属性呢?如果需要的话,我习惯于在 JS 中为任何东西添加属性——函数、数组、冰淇淋甜筒等等。但在这种情况下似乎是不可能的,至少在我能想到的任何方面都是不可能的。
Object.defineProperty(this.thing, 'id', {...}) // <-- error
当然,我可以简单地在 Constructor 对象本身上定义一个属性,例如“thingID”,或者我可以从事物 getter 中返回名称和 ID。我不是在寻找这样的解决方案,无论多么明显;这是一个关于是否实际上可以在已定义属性上定义属性的假设问题。