Javascript class setter 每个属性

Javascript class setter on each attribute

我正在尝试创建一个 class,其中有许多对象被指定为属性。我坚持在这些属性上实施 setters。

下面是失败的例子。当我执行 record1.foo = 'bar'; // record.foo is now a string 时,我用字符串覆盖属性,而不是在元素 class.

中设置值

希望这是有道理的,我想要一个 setter 将值写入元素而不是替换它。

'use strict';

const assert = require('chai').assert;

class Element {

  constructor(name) {
    this.name = name;
    this.value = null;
  }

  getValue() {
    return this.value;
  }

  setValue(value) {
    this.value = value;
  }

  getName() {
    return this.name;
  }

  toString() {
    return this.getValue();
  }

}

class Record {

  constructor() {
    this.fields = ['name', 'age', 'foo'];
    this.fields.forEach((field) => {
      this[field] = new Element(field);
    });
  }

  setValue(field, value) {
    this[field].setValue(value);
  }

  getValue(field) {
    return this[field].getValue();
  }

}

let record1 = new Record();
record1.name.setValue('Bob');
record1.setValue('age', 42);

assert.equal(record1.getValue('name'), 'Bob');
assert.equal(record1.age, 42);

console.log('so far so good');

record1.foo = 'bar'; // record.foo is now a string
assert.equal(record1.getValue('foo'), bar);

据我所知,这就是你想要的:

class Delegator {
  set foo (a) {
    this._foo.value = a;
  }

  get foo () {
    return this._foo.value;
  }

  constructor () {
    let fields = ['foo', 'value', 'name'];
    fields.forEach(fld => this[`_${fld}`] = new Element(fld));
  }
}

let instance = new Delegator();
instance.foo; // returns Element's value of foo
instance.foo = 'bar'; // sets Element's value to bar

作为按照您想要的方式进行的动态方式,试试这个:

'use strict';

class Element {

  constructor(name) {
    this.name = name;
    this.value = null;
  }

  getValue() {
    return this.value;
  }

  setValue(value) {
    this.value = value;
  }

  getName() {
    return this.name;
  }

  toString() {
    return this.getValue();
  }

}

class Record {

  constructor() {
    this.fields = ['name', 'age', 'foo'];
    this.fields.forEach((field) => {
      let element = new Element(field);
      Object.defineProperty(this, field, {
        set: function(value) {
          element.setValue(value);
        },
        get: function() {
          return element;
        }
      });
    });
  }

  setValue(field, value) {
    this[field].setValue(value);
  }

  getValue(field) {
    return this[field].getValue();
  }

}

let record1 = new Record();
record1.name.setValue('Bob');
record1.setValue('age', 42);

console.log(record1.getValue('name') === 'Bob');
console.log(record1.age === 42);

record1.foo = 'bar';
console.log(record1.getValue('foo') === 'bar');