你能用setter在一个属性上添加额外的属性吗

Can you add additional properties on a property with a setter?

本文关键字:属性 添加 一个 setter      更新时间:2023-09-26

我正在尝试为一种类型的数据对象创建一个包装器。我希望能够在包装器上定义一个属性,该属性在更改时具有以下两个效果:

  1. 更改包装数据对象中相应属性的值
  2. 将单个更改的记录添加到迄今为止所有更改的列表中

最近才知道它的存在,JavaScript内置的getter和setter功能(特别是setter)似乎就是这项工作的工具。问题是:我试图使其尽可能地大致符合现有的API,并且有问题的API字段不一定支持直接获取值,而是查询属性以查看它是否符合某些条件。

例如,我可能有一个属性为car.colorcar对象。我希望能够通过只说car.color = "blue";来设置这个属性,但我也希望能够调用一个函数car.color.isBlue();,无论该属性的值是"蓝色"、"蓝色"或"#0000FF",还是我希望封装在函数中而不是每次直接与值进行比较的许多情况中的任何一种,它都会返回true。

当然,我可以通过指定一个显式的property.set(value)函数来轻松地做到这一点,但在我看来,这就像cruft一样,如果可能的话最好避免:它感觉不像=的赋值那么自然,并消除了修改属性和查询属性之间的(IMO)良好语法区别。

这感觉像是JavaScript(作为一种普遍的风气)应该足够灵活来支持的东西,但我尝试过的都没有真正奏效。那么,这真的有可能吗?更主观地说,如果答案是肯定的,那么我有什么令人信服的理由不这么做吗?

您可以让getter返回一个具有isBlue函数的对象。

类似的东西

function ColoredThing(color){
    var colorValue = color;
    var colorProperty = { isBlue: function(){
        return colorValue === "blue";
    }}
    Object.defineProperty(this, "color",{
        get: function(){
            return colorProperty;
        },
        set: function(color){
            //track history, whatever.
            colorValue = color;
        }
    });
};

然后

    var thing = new ColoredThing("blue");
    var color = thing.color
    var isBlue = color.isBlue(); //isBlue == true
    thing.color = "red";
    isBlue = color.isBlue(); //isBlue == false