Установка класса Javascript для каждого атрибута
Я пытаюсь создать класс, который имеет ряд объектов, назначенных в качестве атрибутов. Я застрял на реализации сеттеров на этих атрибутах.
Неудачный пример ниже. Когда я делаю record1.foo = 'bar'; // record.foo is now a string
Я перезаписываю атрибут строкой, а не устанавливаю значение внутри класса Element.
Надеюсь, что это имеет смысл, я бы хотел, чтобы установщик записал значение в элемент, а не заменил его.
'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);
2 ответа
Решение
Как динамичный способ сделать это так, как вы хотите, попробуйте это:
'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');
Насколько я могу сказать, это то, что вы хотите:
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