#javascript #mixins #getter
#javascript #mixins #средство получения
Вопрос:
У меня есть готовые микшины с установщиком и получателем:
const dataentity_compnts_mixins = {
set within_context(val_obj) {
switch (val_obj["dataentity_morphsize"]) {
case 'compact':
this.shadow_wrapper.setAttribute(
"within-context", "compact_dataentity");
break;
case 'expanded':
this.shadow_wrapper.setAttribute(
"within-context", "expanded_dataentity");
break;
}
},
get within_context() {
const host_dataentity = this.parent_dataentity ||
this.closest('independent-data-entity') ||
this.closest('dependent-data-entity');
this.parent_dataentity = host_dataentity;
const context_dict = {
"dataentity_morphsize": host_dataentity.getAttribute("morph-size"),
"dataentity_role": host_dataentity.getAttribute("entity-role")
};
return context_dict;
}
};
затем я использую Object.assign
, чтобы объединить это с прототипом моего пользовательского элемента:
Object.assign(IndividualviewEditor.prototype, dataentity_compnts_mixins); [1]
Я ожидал, что получатель и установщик не будут оцениваться до тех пор, пока не будут вызваны со this
ссылкой на объект хоста, который в моем случае является IndividualviewEditor
пользовательским элементом. Однако при запуске этого кода на моей веб-странице я получил сообщение об ошибке:
Uncaught TypeError: this.closest is not a function ...
Я проверил стек вызовов, который предполагает, что средство получения вызывается строкой [1] .
Я сделал много поисковых запросов в Google и полностью заблудился. Этот геттер вычисляется при объединении с моим прототипом?? это намного раньше, чем я ожидал.
Ответ №1:
Object.assign
копирует все собственные перечислимые свойства влево, что означает, что получатели извлекаются, а их возвращаемое значение копируется, но сама функциональность getter теряется.
const mixin = {
get random() {
console.log('I am mixin', this === mixin);
return Math.random();
}
};
const reference = {};
Object.assign(reference, mixin);
console.log("-------");
С помощью этого кода вы будете читать в консоли I am mixin true
, потому random
что средство доступа извлекается во время копирования.
reference.random
Действительно, он всегда будет указывать на одно и то же число, сгенерированное только во время Object.assign
операции.
Для неглубокого копирования свойств вам нужно передать дескрипторы, а примитивами для этого являются Object.defineProperties
и Object.getOwnPropertyDescriptors
.
Давайте попробуем еще раз:
const mixin = {
get random() {
console.log('I am mixin', this === mixin);
return Math.random();
}
};
const reference = {};
Object.defineProperties(
reference,
Object.getOwnPropertyDescriptors(mixin)
);
console.log("-------");
console.log(reference.random);
reference.random = 4; //no setter - nothing happens
console.log(reference.random);
Первое, на что следует обратить внимание, это то, что вы ничего не будете читать в консоли, потому что средство доступа, ну, не доступно.
Однако всякий раз, когда вы получаете доступ reference.random
, вы будете читать, что это не mixin
контекст, и каждый раз он будет возвращать новое случайное значение.
Всякий раз, когда вы хотите определить микшины для классов или простых объектов, Object.defineProperties
это правильный путь.