Метод получения JavaScript для всех свойств
-
13-09-2019 - |
Вопрос
Короче говоря:Я нахожусь в ситуации, когда мне нужен геттер в стиле PHP, но на JavaScript.
Мой JavaScript работает только в Firefox, поэтому JS для Mozilla меня устраивает.
Единственный способ создать геттер JS требует указания его имени, но я бы хотел определить геттер для все возможные имена.Я не уверен, возможно ли это, но мне бы очень хотелось знать.
Решение
Proxy
может сделать это!Я так рада, что это существует!!Ответ дан здесь: Существует ли javascript-эквивалент метода __getattr__ Python? .Перефразирую своими словами:
var x = new Proxy({},{get(target,name) {
return "Its hilarious you think I have "+name
}})
console.log(x.hair) // logs: "Its hilarious you think I have hair"
Прокси на победу!Ознакомьтесь с документацией MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Работает в Chrome, Firefox и Node.js.Недостатки:не работает в IE - чертов IE.Скоро.
Другие советы
Самое близкое, что вы можете найти, это __noSuchMethod__, который является эквивалентом PHP __call() в JavaScript.
К сожалению, не существует эквивалента __get/__set, и это досадно, потому что с их помощью мы могли бы реализовать __noSuchMethod__, но я пока не вижу способа реализовать свойства (как в C#) с помощью __noSuchMethod__.
var foo = {
__noSuchMethod__ : function(id, args) {
alert(id);
alert(args);
}
};
foo.bar(1, 2);
Если вы пишете код на ES6, вы можете объединить прокси и класс, чтобы получить красивый код, такой как php:
class Magic {
constructor () {
return new Proxy(this, this);
}
get (target, prop) {
return this[prop] || 'MAGIC';
}
}
это привязывается к обработчику, поэтому вы можете использовать его вместо цели.
Примечание:в отличие от PHP, прокси обрабатывает все запросы свойств.
let magic = new Magic();
magic.foo = 'NOT MAGIC';
console.log(magic.foo); // NOT MAGIC
console.log(magic.bar); // MAGIC
Вы можете проверить, какие браузеры поддерживают прокси http://caniuse.com/#feat=proxy и класс http://caniuse.com/#feat=es6-класс.Узел 8 поддерживает оба.
Джаваскрипт 1.5 имеет геттер/сеттер синтаксический сахар.Это очень хорошо объяснил Джон Резиг. здесь
Он недостаточно универсален для использования в Интернете, но они наверняка есть в Firefox (а также в Rhino, если вы когда-нибудь захотите использовать его на стороне сервера).
Если вам действительно нужна работающая реализация, вы можете «обмануть» свой путь, проверив второй параметр на соответствие undefined
, это также означает, что вы можете использовать get для установки параметра.
var foo = {
args: {},
__noSuchMethod__ : function(id, args) {
if(args === undefined) {
return this.args[id] === undefined ? this[id] : this.args[id]
}
if(this[id] === undefined) {
this.args[id] = args;
} else {
this[id] = args;
}
}
};
Если вы ищете что-то вроде PHP __get()
функция, я не думаю, что Javascript предоставляет такую конструкцию.
Лучшее, что я могу придумать, — это перебрать нефункциональные члены объекта и затем создать для каждого соответствующую функцию «getXYZ()».
В хитроумном псевдокоде:
for (o in this) {
if (this.hasOwnProperty(o)) {
this['get_' + o] = function() {
// return this.o -- but you'll need to create a closure to
// keep the correct reference to "o"
};
}
}
В итоге я использовал ответ Nickfs, чтобы создать собственное решение.Мое решение автоматически создаст функции get_{propname} и set_{propname} для всех свойств.Прежде чем добавлять, он проверяет, существует ли функция.Это позволяет вам переопределить метод get или set по умолчанию с помощью нашей собственной реализации без риска его перезаписи.
for (o in this) {
if (this.hasOwnProperty(o)) {
var creategetter = (typeof this['get_' + o] !== 'function');
var createsetter = (typeof this['set_' + o] !== 'function');
(function () {
var propname = o;
if (creategetter) {
self['get_' + propname] = function () {
return self[propname];
};
}
if (createsetter) {
self['set_' + propname] = function (val) {
self[propname] = val;
};
}
})();
}
}