grabbee
@grabbee

Как передать значение по умолчанию для объекта по ссылке?

Нужна возможность добавлять объекты в список со значением по умолчанию равным общему для всех. Это значение в будущем можно будет изменить, и ожидается, что это изменит все свойства у объектов списка указанные(ссылающиеся на это значение) при добавлении. Можно будет изменить напрямую свойство объекта со значения по умолчанию на другое, тогда изменение значения по умолчанию изменит свойство у всех объектов, кроме этого.

Набросал такой код, но он не работает как ожидается.

function Some() {
  this.name = 'Some'; 
}
function Other() {
  this.name = 'Other'; 
}

function Filters() {
  this.handler = new Some();  
  this.list = { };
  this.add = function (name, filter) { 
    this.list[name] = Object.create({
      handler: this.handler,
    });
  }
} 

let attempt = new Filters();
attempt.add('first');
attempt.handler = new Other(); 

document.writeln(attempt.handler.name);
document.writeln(attempt.list['first'].handler.name);


В итоге, значение prop у объектов списка не изменяется, хотя ожидалось, что оба значения будут other.
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
Lynn
@Lynn
nginx, js, css
Можно написать что-то такое с использованием прототипов:

class Filters {
    constructor(x) {
        this.default = { prop: 'foo' };
        this.list = {};
    }

    add(name) {
        this.list[name] = Object.create(this.default);
    }
}

let attempt = new Filters();
attempt.add('first');
attempt.add('second');
attempt.list['second'].prop = 'custom';

console.log(attempt.list['first'].prop, attempt.list['second'].prop);
// → foo custom
attempt.default.prop = 'bar';
console.log(attempt.list['first'].prop, attempt.list['second'].prop);
// → bar custom


Или поразвлекатся с Object.defineProperty
class Filters {
    constructor(x) {
        this.prop = 'foo';
        this.list = {};
    }

    add(name) {
        const item = this.list[name] = Object.defineProperty({}, 'prop', {
            enumerable: true,
            configurable: true,
            get: () => this.prop,
            set: (v) => {
                Object.defineProperty(item, 'prop', {
                    enumerable: true,
                    writable: true,
                    value: v
                });
            }
        });
    }
}

let attempt = new Filters();
attempt.add('first');
attempt.add('second');
attempt.list['second'].prop = 'custom';

console.log(attempt.list['first'].prop, attempt.list['second'].prop);
// → foo custom

attempt.prop = 'bar';
console.log(attempt.list['first'].prop, attempt.list['second'].prop);
// → bar custom
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы