使用相同的getter和setter创建多个属性

马克·博内利

问题

最近我一直在写一些JavaScript程序,其中涉及gettersetter的使用我阅读了两种方法的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
});

然后,我为foobar属性分配了新值,如下所示:

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__and__defineGetter__函数,但是结果没有改变。

我的问题

现在,在解决我的问题的几次失败尝试之后,我想知道:

  • 是否可以在对象的不同属性上定义相同的setter和getter?
  • 如果是这样,我在做什么错,为什么我的属性表现得像是同一属性?
  • 有没有更好的方法来完成我想做的事情(可能无需为每个属性编写每个setter和getter)?
贝吉

是否可以在对象的不同属性上定义相同的setter和getter?

是的,尽管根据您的经验不建议这样做,但不建议这样做。

我在做什么错,为什么我的属性表现得像是同一属性?

因为它们存储/访问值,所以设置/获取的值始终存储在.value对象的同一属性中:myObj.value == 6所以myObj.foomyObj.baryield都一样7

有什么更好的方法可以完成我想做的事情?

将值存储在闭包作用域变量中,并使用函数定义属性:

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");

当然,除了使用局部变量之外,您还可以简单地使用不同的“内部”属性,并且还可以使用通过函数创建公共设置器/获取器的其他方法。两者都适用:

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")
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Swift:使用相同的Getter和/或Setter的计算属性

具有相同的预定义属性名称时使用getter和setter

德尔福 | 是否可以对属性使用相同的 Getter/Setter?

是否可以对属性使用相同的 Getter/Setter?

覆盖属性的getter和setter

如何创建getter和setter

Doctrine 创建 setter 和 getter?

使用getter和setter与在JavaScript中定义属性

何时将 getter 和 setter 与属性一起使用?

使用 getter 和 setter 调用实例属性好不好?

使用@Data后,Lombok不会创建getter和setter方法

使用@property与getter和setter

具有相同属性的setter和getter引发eslint签名应为相邻错误

限制 getter 和 setter 可访问的属性

Haxe属性-与@:isVar的getter和setter

swift 属性空的 setter 和 getter

如何创建getter和setter覆盖?

何时使用JavaFX属性setter和getter,而不是直接使用属性

在具有自己属性的对象属性上使用getter和setter

在Spring Boot中,如何使用扩展的setter和getter设置(扩展的)属性?

使用 getter 和 setter 方法将列表添加到 bean 属性之间的区别?

Swift为什么不像Java或C#那样使用getter和setter作为属性?

您只能同时使用setter和getter的计算变量来覆盖超类的存储属性

角度2:如何使用getter和setter方法将Input绑定到模型属性?

如何在具有getter和setter的属性上使用Aurelia的可绑定装饰器

使用Django Rest Framework从模型序列化属性(getter和setter)的问题

在python 2.7中的getter和setter上使用属性时发生意外行为

如何使用 Roslyn 在 C# 中忽略属性 Getter 和 Setter

使用Eclipse的布尔型Getter和Setter