Pergunta

Para encurtar a história:. Eu estou em uma situação onde eu gostaria de um getter-style PHP, mas em JavaScript

O meu JavaScript é executado no Firefox somente, assim Mozilla específica JS é OK por mim.

A única maneira que eu posso encontrar para fazer um getter JS requer especificando o seu nome, mas eu gostaria de definir um getter para todas nomes possíveis. Eu não tenho certeza se isso é possível, mas eu gostaria muito de saber.

Foi útil?

Solução

Proxy pode fazê-lo! Estou tão feliz isso existe !! Uma resposta é dada aqui: Existe uma javascript equivalente a __getattr__ de python método? . Para reformular em minhas próprias palavras:

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"

Proxy para a vitória! Confira o MDN docs: https: //developer.mozilla .org / pt-bR / docs / web / JavaScript / Referência / Global_Objects / Proxy

Obras em Chrome, Firefox, e Node.js. Desvantagens: não funciona no IE - maldito IE. Em breve.

Outras dicas

O mais próximo que você pode encontrar é __noSuchMethod__ , que é de JavaScript equivalente a __call () do PHP.

Infelizmente, não há equivalente a __get / __ set, que é uma vergonha, porque com eles, poderíamos ter implementado __noSuchMethod__, mas eu ainda não vejo uma maneira de implementar propriedades (como em C #) usando __noSuchMethod __.

var foo = {
    __noSuchMethod__ : function(id, args) {
        alert(id);
        alert(args);
    }
};

foo.bar(1, 2);

Se você está codificando em ES6 você pode combinar proxy e classe para ter um boa aparência código como php :

class Magic {
    constructor () {
        return new Proxy(this, this);
    }
    get (target, prop) {
        return this[prop] || 'MAGIC';
    }
}

Isso vincula para o manipulador, assim você pode usar isso em vez de alvo.

Nota:. Ao contrário de PHP, alças de proxy todo o pedido Propriedade

let magic = new Magic();
magic.foo = 'NOT MAGIC';
console.log(magic.foo); // NOT MAGIC
console.log(magic.bar); // MAGIC

Você pode verificar quais navegadores de proxy apoio http://caniuse.com/#feat=proxy e classe http://caniuse.com/#feat=es6-class . Nó 8 suporte ambos.

Javascript 1,5 tem getter / setter sintática açúcar. É muito bem explicado por John Resig aqui

Não é suficiente genérico para uso da web, mas certamente Firefox tem deles (também Rhino, se você quiser usá-lo no lado do servidor).

Se você realmente precisa de uma implementação que funciona, você poderia "enganar" o seu caminho espalhados testando o segundo parâmetro contra undefined, isso também significa que você poderia usar chegar ao parâmetro realmente set.

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;
        }
    }
};

Se você está procurando algo como do PHP __get() função, eu não acho que o Javascript fornece qualquer construção.

O melhor que posso pensar em fazer é looping através de membros não-função do objeto e, em seguida, a criação de um "getXYZ ()" correspondente função para cada um.

No código pseudo-ish desonesto:

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"
        };
    }
}

Acabei usando responder a uma nickfs para construir a minha própria solução. Minha solução criará automaticamente get_ {propname} e {set_ PROPNAME} funções para todas as propriedades. Ele verifique se a função já existe antes de adicioná-los. Isso permite que você substituir o get padrão ou método conjunto com a nossa própria implementação sem o risco de ele ficar substituído.

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;
                    };
                }
            })();
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top