JavaScript getter для всех свойств
короче говоря: я нахожусь в ситуации, когда я хотел бы получить PHP-стиль, но в JavaScript.
мой JavaScript работает только в Firefox, поэтому Mozilla specific JS в порядке.
единственный способ, которым я могу найти, чтобы сделать геттер JS, требует указания его имени, но я хотел бы определить геттер для все возможные названия. Я не уверен, что это возможно, но мне очень хотелось бы знать.
7 ответов
вы можете найти __noSuchMethod__, что является эквивалентом JavaScript для PHP __call().
к сожалению, нет эквивалента__get/ _ _ set, что позорно, потому что с ними мы могли бы реализовать __noSuchMethod__, но я пока не вижу способа реализовать свойства (как в C#) с помощью __noSuchMethod__.
var foo = {
__noSuchMethod__ : function(id, args) {
alert(id);
alert(args);
}
};
foo.bar(1, 2);
Proxy
можете сделать это! Я так рада, что это существует!! Здесь дается ответ:существует ли javascript-эквивалент метода __getattr _ _ python? . Перефразируя мои собственные слова:--5-->
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 - freakin IE. Скоро.
Если вы кодируете в ES6, вы можете объединить прокси и класс, чтобы иметь красивый код, такой как php:
class Magic {
constructor () {
return new Proxy(this, this);
}
get (target, prop) {
return this[prop] || 'MAGIC';
}
}
это привязывается к обработчику, поэтому вы можете использовать это вместо target.
Примечание: В отличие от 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-class. Узел 8 поддерживать как.
Javascript 1.5 есть геттер/сеттер синтаксический сахар. Это очень хорошо объяснил Джон Resig здесь
Это не достаточно общий для веб-использования, но, конечно, Firefox имеет их (также носорог, если вы когда-нибудь захотите использовать его на стороне сервера).
Если вам действительно нужна реализация, которая работает, вы можете "обмануть" свой путь, Протестировав второй параметр против 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;
};
}
})();
}
}