概括类型化setter和getter的最佳方法是什么?

时间:2019-02-05 14:50:58

标签: javascript ecmascript-6

在此类中归纳设置方法和获取方法的最佳方法是什么?

class A {
    constructor() {
        this._foo = new Foo();
        this._bar = new Bar();
    }

    get foo() {
        return this._foo;
    }

    set foo(value) {
        if (value instanceof Foo)
            this._foo = value;
        else
            this._foo = Object.assign(new Foo(), value);
    }

    get bar() {
        return this._bar;
    }

    set bar(value) {
        if(value instanceof Bar)
            this._bar = value;
        else
            this._bar = Object.assign(new Bar(), value);
    }
}

修改

是的,该问题可以基于观点,并且可以使用键入的语言解决。但是如何在es6中为没有迁移选项的现有项目解决该问题?

在反序列化存储在数据库中的json文档后,我需要这个设置器来定义成员的类型:

{
    "foo" :{"x":0,"y":0,"z":0},
    "bar" : {"propA": "valueA", "propB": "valueB"}
}

2 个答案:

答案 0 :(得分:3)

理论上可以使用混合:

<div class="container">
  <div class="left">
    <ul>
      <li>aaaa</li>
      <li>bbbb</li>
      <li>cccc</li>
    </ul>
  </div>
  <div class="right">
    <img src="https://via.placeholder.com/200"/>
  </div>
</div>

但是您可能根本不应该使用getter / setter方法,而应该修复尝试使用无效值设置属性的代码。

答案 1 :(得分:2)

如果您想抽象设置器/获取器的创建,那么您当然可以编写一个函数来做到这一点:

function typedAccessor(obj, name, type, internal) {
    Object.defineProperty(obj, name, {
        get() {
            return this[internal];
        },
        set(val) {
            if (val instanceof type)
                this[internal] = val;
            else
                this[internal] = Object.assign(new type, val);
        }
    });
}

class A {
    constructor() {
        this._foo = new Foo();
        this._bar = new Bar();
    }
}
typedAccessor(A.prototype, "foo", Foo, "_foo");
typedAccessor(A.prototype, "bar", Bar, "_bar");

但是我会recommend来避免这种模式。

  

在反序列化json文档后,我需要此设置器来定义成员的类型

最好使用自定义静态方法,该方法比Object.assign知道如何处理JSON表示(并希望所有东西都有适当的设置器)。这使您可以更好地控制序列化/反序列化过程,并使用更少的样板代码简化类。

class A {
    constructor(foo, bar) {
        this.foo = foo;
        this.bar = bar;
    }
    static fromJSON(val) {
        return new this(Foo.fromJSON(val.foo), Bar.fromJSON(val.bar);
    }
}