最近我一直在写一些涉及使用getters和setters的JavaScript程序.我阅读了两种方法的MDN文档,但是我很困惑尝试使用它们.
简而言之,我只想创建一系列类似的属性,它们具有相同的getter和setter,但我不想为每个属性重写每个setter和getter.
履行
var defaultProperty = { set: function(val) { this.value = val - 1; // Just an example },get: function() { return this.value + 1; // Just an example } }; var myObj = {}; Object.defineProperties(myObj,{ foo: defaultProperty,bar: defaultProperty });
然后我为我的foo和bar属性分配了新值,如下所示:
myObj.foo = 3; myObj.bar = 7;
最后,我期待这样的事情:
console.log(myObj.foo,myObj.bar); > 3 7
但我意外地得到了这个:
> 7 7
看起来这两个属性要么指向相同的内存地址,要么共享相同的setter / getter.注意到这一点,我试图解决问题,并分别创建每个属性,如下所示:
Object.defineProperties(myObj,{ foo: { set: function(val) { this.value = val - 1; },get: function() { return this.value + 1; } },bar: { set: function(val) { this.value = val - 1; },get: function() { return this.value + 1; } } });
但结果是一样的:
myObj.foo = 3; myObj.bar = 7; console.log(myObj.foo,myObj.bar); > 7 7
我也尝试使用__defineSetter__和__defineGetter__函数,但结果没有改变.
我的问题
现在,在几次尝试解决我的问题失败之后,我想知道:
>是否可以在对象的不同属性上定义相同的setter和getter?
>如果是这样,我做错了什么,为什么我的属性表现得像他们是同一个属性?
>有没有更好的方法来完成我正在尝试做的事情(可能没有为每个属性编写每个setter和getter)?
解决方法
Is it possible to define the same setters and getters on different properties of an object?
是的,虽然不建议您从经验中看到.
what am I doing wrong,and why do my properties behave like they’re the same property?
因为它们存储/访问所设置/获取的值总是存储在对象的相同.value属性中:myObj.value == 6所以myObj.foo和myObj.bar都会产生7.
Is there any better method to accomplish what I’m trying to do?
function makeDefaultProperty(obj,name) { var value; return Object.defineProperty(obj,name,{ set: function(val) { value = val - 1; // Just an example },get: function() { return value + 1; // Just an example } }); }; var myObj = {}; makeDefaultProperty(myObj,"foo"); makeDefaultProperty(myObj,"bar");
当然,您可以使用不同的“内部”属性来代替局部变量,也可以使用不同的方法通过函数创建公共setter / getter.两者均适用:
function defaultProperty(name) { return { set: function(val) { this[name] = val - 1; // Just an example },get: function() { return this[name] + 1; // Just an example } }; } var myObj = Object.defineProperties({},{ foo: defaultProperty("_foo"),bar: defaultProperty("_bar") });