Proxy JavaScript
js
const persona1 = {
name: 'bingus',
age: '5 year',
job: false,
}
const persona2 = {
name: 'floppa',
age: '5 year',
job: false,
}
const handler = {
get( target , prop){
console.log(`this ${prop} target value: ${target[prop]}`);
return target;
}
}
Object.prototype.morePersonInfo = new Proxy( Object 'как его менять динамически?' , handler); // пытался так, но по понятным на то причинам, это не сработало
Как динамично применять proxy для объектов? Очень нуждаюсь в вашей помощи.
пример console:
persona1.morePersonInfo // вывод того что мне нужно через proxy для persona1
persona2.morePersonInfo // вывод того что мне нужно через proxy для persona2
Ответы (2 шт):
Не уверен, правильно ли я понимаю. Если вы хотите, чтобы при обращении к любому свойству любого объекта происходило обращение к прокси без какого-либо вмешательства в сам объект, то это вряд ли возможно. Наверное, вы бы хотели превратить Object.prototype в прокси, но это невозможно, потому что Object.prototype только для чтения.
Так что у вас есть выбор: 1) назначить прототипом всех нужных объектов ваше Proxy — но этого делать не рекомендуют, так как изменение прототипа может замедлить работу с объектом и само по себе является медленной операцией; 2) сразу задать прототипом прокси через __proto__ в литерале — но зачем такая сложность, если можно просто создавать объекты как проксированные?
Не это ли вам нужно?
const handler = {
get(target , prop){
console.log(`this ${prop} target value: ${target[prop]}`);
return target[prop];
}
};
const persona1 = new Proxy({
name: 'bingus',
age: '5 year',
job: false,
}, handler);
const persona2 = new Proxy({
name: 'floppa',
age: '5 year',
job: false,
}, handler);
persona1.morePersonInfo;
persona2.morePersonInfo;
Технически, можно использовать Object.defineProperty чтобы получить что-то подобное... Внутри геттера this будет ссылаться на текущий объект.
const person1 = {
name: 'bingus',
age: '5 year',
job: false,
};
const person2 = {
name: 'floppa',
age: '5 year',
job: false,
};
Object.defineProperty(Object.prototype, "morePersonInfo", {
get() {
console.log("*", this);
return this.name + ', ' + this.age;
}
});
console.log( person1.morePersonInfo );
console.log( person2.morePersonInfo );
code { white-space: nowrap !important }
Но все эти прокси, геттеры и прочая экзотика используются в очень редких случаях. Например, когда уже написано много кода с использованием одного свойства, а вдруг оказалось, что это свойство должно выдать какое-то специфичное значение в определенных условиях. Может быть удобнее заменить его на геттер, чем всё переписать.
Если функция и так заранее предусмотрена, было бы уместно явно сделать её методом этих объектов, а не замаскировать её под свойтво. А для этого есть такие варианты:
- Вручную выдать им свойство-функцию (не очень удобно):
function morePersonInfo() {
return this.name + ', ' + this.age;
}
const person1 = {
name: 'bingus',
age: '5 year',
morePersonInfo, // Вместо morePersonInfo: morePersonInfo
// Сокращение работает, когда названия свойства и значения одинаковые.
};
const person2 = {
name: 'floppa',
age: '5 year',
morePersonInfo,
};
console.log( person1.morePersonInfo() );
console.log( person2.morePersonInfo() );
- Создать объект с набором методов и сделать его "родительским" для ваших объектов:
const person = (function() {
const _methods = {
morePersonInfo() {
return this.name + ', ' + this.age;
},
moo() {
console.log("Moo...");
},
};
return function(obj) {
Object.setPrototypeOf(obj, _methods);
return obj;
}
})();
const person1 = person({
name: 'bingus',
age: '5 year',
});
const person2 = person({
name: 'floppa',
age: '5 year',
});
person1.moo();
console.log( person2.morePersonInfo() );
- Изначально создавать объекты с помощью Классов
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
this.job = false;
}
morePersonInfo() {
return this.name + ', ' + this.age;
}
moo() {
console.log("Moo...");
}
}
const person1 = new Person('bingus', '5 year');
const person2 = new Person('floppa', '5 year');
person1.moo();
console.log( person2.morePersonInfo() );
Конечно, из таких примеров не очевидно, какой вариант выбрать. Нужно рассматривать это всё в контексте конкретной задачи.