3 votes

La valeur de "this" en javascript change, mais je ne comprends pas pourquoi.

Je suis totalement novice en Javascript et j'essaie de me faire une idée d'OLN. Ce que je rencontre, c'est que, lorsque j'appelle une méthode objet à partir d'une autre méthode sur le même objet, la valeur de la valeur locale de 'this' dans la méthode appelée change. Voici mon code :

var generator = {
    generateForLevelSkillAndCount : function(level, skill, count) {
        var functionCall = this['generate_' + level + '_' + skill];
        return functionCall(count);
    },
    generate_0_4 : function(count) {
        return this.generate_generic_dots(count, 3);
    },
    generate_generic_dots : function(count, maxDots) {
        /* do cool stuff and return it */
    }
};

Donc, j'appelle generator.generateForLevelSkillAndCount(0, 4, 20) et cela fonctionne correctement, en appelant generate_0_4(count) . Cependant, c'est là qu'il échoue, la console Javascript de Chrome m'indiquant "Uncaught TypeError : Object [object DOMWindow] has no method 'generate_generic_dots'".

J'en sais assez pour savoir que le problème est que la valeur de this en generate_0_4 est un objet DOMWindow, plutôt qu'un générateur (ce qui est le cas de l'objet this pointe vers dans generateForSkillLevelAndCount mais je n'arrive pas à comprendre pourquoi ça pourrait arriver.

Mise à jour : J'ai mis à jour le code d'exemple selon la suggestion de CMS pour se débarrasser de eval mais la même erreur est renvoyée, ce qui signifie qu'il ne s'agit pas seulement d'un problème de sécurité. eval bogue.

0voto

Tgr Points 11766

Il s'agit d'une caractéristique de Javascript : la valeur de l'option this dépendra de l'objet à partir duquel la fonction a été appelée, et non de l'endroit où elle a été définie. (Ce qui est logique lorsque les fonctions sont elles-mêmes des objets de première classe). this dans la plupart des autres contextes, fait référence à l'objet fenêtre.

Il existe deux solutions de contournement courantes, qui consistent à utiliser une fonction wrapper :

function bind(func, obj) {
    return function() {
        func.apply(obj, arguments);
    }
}

ou en utilisant une fermeture :

var self = this;
function generate_blah() {
    // use self instead of this here
}

Dans votre cas, cependant, il suffit de remplacer

var functionCall = this['generate_' + level + '_' + skill];
return functionCall(count);

con

this['generate_' + level + '_' + skill](count);

ferait l'affaire.

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