Question

Longue histoire courte. Je suis dans une situation où je voudrais un getter de style PHP, mais en JavaScript

Mon JavaScript est en cours d'exécution dans Firefox uniquement, si Mozilla JS spécifique est OK par moi.

La seule façon que je peux trouver pour faire un getter JS nécessite de spécifier son nom, mais je voudrais définir un getter pour tous noms possibles. Je ne sais pas si cela est possible, mais je voudrais bien savoir.

Était-ce utile?

La solution

Proxy peut le faire! Je suis tellement heureux ça existe !! Une réponse est donnée ici: Y at-il un équivalent javascript de __getattr__ de python méthode? . Pour reformuler dans mes propres mots:

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 pour la victoire! Consultez les docs MDN: https: //developer.mozilla .org / fr-fr / docs / Web / JavaScript / Référence / Global_Objects / Proxy

Works en chrome, firefox, et Node.js. Downsides: ne fonctionne pas dans IE - IE connerie. Bientôt.

Autres conseils

Le plus proche que vous pouvez trouver est __noSuchMethod__ , qui est l'équivalent JavaScript de __call de PHP ().

Malheureusement, il n'y a pas d'équivalent de __get / __ jeu, ce qui est dommage, parce qu'avec eux, nous aurions pu mis en œuvre __noSuchMethod__, mais je ne vois pas encore un moyen de mettre en œuvre des propriétés (comme en C #) en utilisant __noSuchMethod __.

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

foo.bar(1, 2);

Si vous codez en ES6, vous pouvez combiner procuration et la classe d'avoir un bon Code ressemblant à php :

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

lie au gestionnaire, vous pouvez donc utiliser ce lieu de cible.

Remarque:. Contrairement à PHP, gère toutes les proxy la demande de la propriété

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

Vous pouvez vérifier quels navigateurs prennent en charge proxy http://caniuse.com/#feat=proxy et http://caniuse.com/#feat=es6-class . Support Node 8 fois.

Javascript 1.5 fait avoir getter / setter sucre syntaxique . Il est très bien expliqué par John Resig

Il ne suffit pas générique pour le web, mais certainement Firefox les a (aussi Rhino, si jamais vous voulez l'utiliser sur le côté serveur).

Si vous avez vraiment besoin d'une implémentation qui fonctionne, vous pouvez « tricher » votre chemin arround en testant le second paramètre contre undefined, cela signifie également que vous pouvez utiliser pour obtenir le paramètre réellement défini.

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

Je fini par utiliser une réponse de nickfs pour construire ma propre solution. Ma solution crée automatiquement des fonctions get_ {propname} et {set_ PropName} pour toutes les propriétés. Il ne vérifie si la fonction existe déjà avant de les ajouter. Cela vous permet de passer outre l'obtenir par défaut ou méthode définie avec notre propre mise en œuvre sans le risque de celui-ci s'écrasé.

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;
                    };
                }
            })();
        }
    }
scroll top