55 votes

Est-ce que Javascript a quelque chose qui ressemble à la méthode method_missing de Ruby?

En Ruby, je pense que vous pouvez appeler une méthode qui n’a pas encore été définie et capturer le nom de la méthode appelée et effectuer le traitement de cette méthode au moment de l’exécution.

Javascript peut-il faire le même genre de chose?

45voto

Luciano Ramalho Points 825

method_missing ne cadrent pas bien avec le JavaScript pour la même raison, il n'existe pas en Python: dans les deux langues, les méthodes sont les attributs qui se trouvent être les fonctions et les objets souvent ont des attributs qui ne sont pas remboursables. Le contraste avec Ruby, où l'interface publique d'un objet est de 100% méthodes.

Ce qui est nécessaire dans le JavaScript est un crochet pour attraper l'accès à des attributs manquants, si elles sont des méthodes ou non. Python a: voir l' __getattr__ méthode spéciale.

L' __noSuchMethod__ proposition de Mozilla introduit encore un autre incohérence dans une langue criblé avec eux.

La voie à suivre pour le JavaScript est le mécanisme de Proxy (également dans ECMAscript Harmonie), qui est plus proche du Python protocole pour la personnalisation de l'attribut de l'accès que de Ruby method_missing.

31voto

lmmendes Points 890

Le rubis fonctionnalité que vous expliquant est appelé "method_missing" http://rubylearning.com/satishtalim/ruby_method_missing.htm.

C'est une toute nouvelle fonctionnalité, qui n'est présente que dans certains navigateurs, comme Firefox (dans le singe-araignée moteur Javascript). Dans SpiderMonkey il est appelé "__noSuchMethod__" https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod

Veuillez lire cet article de Yehuda Katz http://yehudakatz.com/2008/08/18/method_missing-in-javascript/ pour plus de détails sur la mise en œuvre à venir.

4voto

Jörg W Mittag Points 153275

Pas pour le moment, non. Il existe une proposition pour ECMAScript Harmony, appelée proxy , qui implémente une fonctionnalité similaire (en réalité beaucoup plus puissante), mais ECMAScript Harmony n'est pas encore sorti et ne le sera probablement pas avant quelques années.

1voto

Peter Lyons Points 47794

Non, il n'y a pas de métaprogrammation capacité en javascript directement analogue à ruby method_missing crochet. L'interprète soulève tout simplement une Erreur, le code d'appel peut attraper, mais ne peut pas être détecté par l'objet en cours d'accès. Il y a quelques réponses ici sur la définition de fonctions au moment de l'exécution, mais ce n'est pas la même chose. Vous pouvez faire beaucoup de métaprogrammation, l'évolution spécifique des instances d'objets, de définir des fonctions, faire fonctionnel des choses comme memoizing et des décorateurs. Mais il n'y a pas de dynamique métaprogrammation de fonctions manquantes, car il est dans ruby ou python.

1voto

Jonny Leeds Points 741

Je suis venu à cette question, parce que je cherchais un moyen de passer à travers à un autre objet si la méthode n'était pas présent sur le premier objet. Ce n'est pas aussi souple que ce que votre demande - par exemple, si une méthode est manquant dans les deux alors il va échouer.

Je pensais faire cela pour une petite bibliothèque que j'ai qui vous aide à configurer extjs objets d'une façon qui les rend également plus vérifiable. J'avais séparé les appels à réellement obtenir la main sur les objets d'interaction et de pensé que cela pourrait être une belle façon de coller à ceux des appels en retour d'un augmentée de type

Je pense à deux façons de le faire:

Prototypes

Vous pouvez le faire à l'aide de prototypes, - que les choses passe à travers le prototype s'il n'est pas sur l'objet réel. Il semble que cela ne fonctionne pas si l'ensemble des fonctions que vous souhaitez déposer par le biais d'utiliser le mot-clé this - évidemment votre objet ne saurez ou de soins sur des choses que l'autre le sait.

Si son de votre propre code et que vous n'utilisez pas cette et les constructeurs ... ce qui est une bonne idée pour des tas de raisons, alors vous pouvez le faire comme ceci:

    var makeHorse = function () {
        var neigh = "neigh";

        return {
            doTheNoise: function () {
                return neigh + " is all im saying"
            },
            setNeigh: function (newNoise) {
                neigh = newNoise;
            }
        }
    };

    var createSomething = function (fallThrough) {
        var constructor = function () {};
        constructor.prototype = fallThrough;
        var instance = new constructor();

        instance.someMethod = function () {
            console.log("aaaaa");
        };
        instance.callTheOther = function () {
            var theNoise = instance.doTheNoise();
            console.log(theNoise);
        };

        return instance;
    };

    var firstHorse = makeHorse();
    var secondHorse = makeHorse();
    secondHorse.setNeigh("mooo");

    var firstWrapper = createSomething(firstHorse);
    var secondWrapper = createSomething(secondHorse);
    var nothingWrapper = createSomething();

    firstWrapper.someMethod();
    firstWrapper.callTheOther();
    console.log(firstWrapper.doTheNoise());

    secondWrapper.someMethod();
    secondWrapper.callTheOther();
    console.log(secondWrapper.doTheNoise());

    nothingWrapper.someMethod();
    //this call fails as we dont have this method on the fall through object (which is undefined)
    console.log(nothingWrapper.doTheNoise());

Cela ne fonctionne pas pour mon cas d'utilisation comme extjs les gars n'ont pas seulement utilisé à tort 'ce' qu'ils ont aussi construit un ensemble de fou classique héritage type de système sur le principe de l'aide de prototypes et "il".

C'est en fait la première fois, j'ai utilisé des prototypes/constructeurs et j'ai été un peu déconcerté que vous ne pouvez pas définir le prototype - vous devez également utiliser un constructeur. Il y a une magie de terrain dans les objets (au moins dans firefox) appel __proto qui est en fait le prototype réel. il semble que le véritable prototype de champ n'est utilisé au moment de la construction... comment la confusion!


Méthodes de copie

Cette méthode est sans doute plus cher, mais semble plus élégant de moi et va aussi travailler sur le code qui est à l'aide de this (par exemple, de sorte que vous pouvez l'utiliser pour envelopper des objets de bibliothèque). Il permettra également de travailler sur des trucs écrits à l'aide de la fonctionnelle/fermeture style aswell - je l'ai dit il avec ce/constructeurs de montrer qu'il travaille avec des trucs comme ça.

Voici les mods:

    //this is now a constructor
    var MakeHorse = function () {
        this.neigh = "neigh";
    };

    MakeHorse.prototype.doTheNoise = function () {
        return this.neigh + " is all im saying"
    };
    MakeHorse.prototype.setNeigh = function (newNoise) {
        this.neigh = newNoise;
    };

    var createSomething = function (fallThrough) {
        var instance = {
            someMethod : function () {
                console.log("aaaaa");
            },
            callTheOther : function () {
                //note this has had to change to directly call the fallThrough object
                var theNoise = fallThrough.doTheNoise();
                console.log(theNoise);
            }
        };

        //copy stuff over but not if it already exists
        for (var propertyName in fallThrough)
            if (!instance.hasOwnProperty(propertyName))
                instance[propertyName] = fallThrough[propertyName];

        return instance;
    };

    var firstHorse = new MakeHorse();
    var secondHorse = new MakeHorse();
    secondHorse.setNeigh("mooo");

    var firstWrapper = createSomething(firstHorse);
    var secondWrapper = createSomething(secondHorse);
    var nothingWrapper = createSomething();

    firstWrapper.someMethod();
    firstWrapper.callTheOther();
    console.log(firstWrapper.doTheNoise());

    secondWrapper.someMethod();
    secondWrapper.callTheOther();
    console.log(secondWrapper.doTheNoise());

    nothingWrapper.someMethod();
    //this call fails as we dont have this method on the fall through object (which is undefined)
    console.log(nothingWrapper.doTheNoise());

J'ai été réellement anticiper d'avoir à utiliser des bind là quelque part, mais il ne semble pas nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X