2009-07-27 5 views
2

Désolé si cela a été répondu, mais je ne pouvais pas trouver une recherche ... une chose difficile à rechercher, je pense!Scoping "this" en Javascript (et jQuery.extend)

Dire que j'ai ceci:

var MyPrototype = function() { this.init(); } 
$.extend(MyPrototype.prototype, { 
    a: 5, 
    init: function() { 
     var thing = new SomeOtherClass(); 
     thing.meth = this.meth; 
     // thing.meth() is called somewhere within thing; 
    }, 
    meth: function() { 
     alert(this.a); 
    } 
} 

Fondamentalement, je traite avec une autre classe qui utilise ses propres méthodes comme, par exemple callbacks Je suis censé les remplacer par mes propres fonctionnalités. Mais j'ai besoin de garder la portée correcte de this en le faisant (la seule chose qui m'importe de SomeOtherClass est ce qui est passé au rappel, rien dans l'état).

Comme vous pouvez l'imaginer, cela ne fonctionne pas car thing n'a pas de propriété a! Je ne suis pas assez familier avec les subtilités du scoping Javascript pour savoir comment faire this se référer à ce que je veux, bien que!

+0

S'il vous plaît voir: http://stackoverflow.com/questions/520019/controlling-the-value-of- this-in-a-jquery-event ... et aussi: http://stackoverflow.com/questions/1043556/how-can-i-keep-the-context-of-this-in-jquery ... et vraiment, la plupart des questions dans: http://stackoverflow.com/questions/tagged/this+javascript (c'est un point de confusion extrêmement commun) – Shog9

Répondre

2

La combinaison de deux autres réponses ici, de sorte que vous n » Je dois réécrire votre fonction meth, je ferais ceci:

var me = this; 
    thing.meth = function() { 
     MyPrototype.meth.apply(me, arguments); 
    }; 
-1

Que diriez-vous:

thing.meth.call(this); 

ou

thing.meth.apply(this); 

(La seule différence est dans la façon dont les arguments sont passés, qui n'a pas d'importance dans ce cas.)

+0

Malheureusement, comme ils sont des rappels lancés à partir de SomeOtherClass, je ne sais pas contrôler réellement comment ils sont appelés. – tdavis

+0

Dans ce cas, il vous suffit d'enrouler le rappel dans une fermeture de sorte que la valeur de "this" soit transportée avec la référence de la fonction. * edsoverflow * a déjà posté un exemple. –

-1

Pourriez-vous faire quelque chose comme ça?

var MyPrototype = function() { this.init(); } 
$.extend(MyPrototype.prototype, { 
    a: 5, 
    init: function() { 
     var thing = new SomeOtherClass(); 
     var self = this; 
     thing.meth = function(){this.meth.apply(self)}; 
     // thing.meth() is called somewhere within thing; 
    }, 
    meth: function() { 
     alert(this.a); 
    } 
} 
+0

Votre "ceci" dans la méthode "helper" qui appelle "meth" a toujours le même problème que celui d'origine. –

+0

L'a modifié pour utiliser self. Fonctionne bien pour moi maintenant. – agilefall

1

Puisque vous ne pouvez pas contrôler la façon dont on l'appelle, vous pouvez essayer ceci:

var MyPrototype = function() { this.init(); } 
$.extend(MyPrototype.prototype, { 
    a: 5, 
    init: function() { 
     var thing = new SomeOtherClass(); 

     // Create an aliad for this 
     var that = this; 
     thing.meth = function() { 
      // You can always access the object using it's "that" alias 
      alert(that.a); 
     }; 
    } 
} 

Ou ...

var MyPrototype = function() { this.init(); } 
$.extend(MyPrototype.prototype, { 
    a: 5, 
    init: function() { 
     var thing = new SomeOtherClass(); 

     // Create an aliad for this 
     var that = this; 
     thing.meth = function() { 
      // You can always access the object using it's "that" alias 
      that.meth(); 
     }; 
    }, 
    meth: { 
     alert(this.a); 
    } 
} 
0

Avant le début de votre exemple de code, ajoutez cette ligne:

var self = this; 

revisser utilisations de « ceci » dans votre code avec « moi ».

(je pense un tas de réponses à ce disent plus ou moins la même chose.)

Questions connexes