Вопрос

Короче говоря:Я нахожусь в ситуации, когда мне нужен геттер в стиле 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;
                    };
                }
            })();
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top