2010-10-07 27 views
2

J'ai vu un tas d'exemples, mais je n'arrive pas à obtenir un exemple de code pour fonctionner."this" mot-clé à l'intérieur

Prenez le code suivant:

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     } 
    } 
}()); 

et j'ai une fonction sur window.load comme:

test.alertT(); 

Que tout fonctionne très bien. Toutefois, lorsque j'essaie de définir explicitement le contexte de t à l'intérieur de l'alerte () dans alertT, je viens d'obtenir indéfini.

J'ai essayé:

var that = this; 
alert(that.t); //undefined 

J'ai essayé:

 return { 
      that: this, 
      alertT: function(){ 
       alert(that.t); // undefined! 
      } 
     } 

et j'ai essayé:

var test = (function(){ 
    var t = "test"; 
    var myObj = this; 
    return { 
     alertT: function(){ 
      alert(myObj.t); // undefined! 
     } 
    } 
}()); 

ce que je manque? Je dois être en mesure de définir le contexte explicitement pour des choses comme les rappels, etc. J'ai aussi vu des exemples (http://stackoverflow.com/questions/346015/javascript-closures-and-this-context) qui ressemblent à ce que je Je fais, alors pourquoi ça ne marche pas?

+0

Pourquoi voulez-vous définir le contexte explicitement? Vos exemples ne le montrent pas vraiment. Soit vous devrez passer un contexte dans la fonction alertT, soit vous devrez utiliser une méthode bind pour lier la fonction à un contexte de votre choix. – Jakob

+0

L'exemple a été décrémenté pour être facile à lire. Je veux être en mesure d'accéder explicitement à la variable over over fermée afin de la transférer dans une autre fonction passée. – hackerhasid

Répondre

1

t est juste une variable normale dans le cadre de la fonction anonyme extérieure (et donc aussi la fonction anonyme interne). Ce n'est pas une propriété sur un objet, donc vous le définissez simplement sans référence à this, that, ou the_other.

var test = (function(){ 
    var t = "test"; 
    return { 
     alertT: function(){ 
      alert(t); 
     }, 
     setT: function (new_value) { 
      t = new_value; 
     } 
    } 
}()); 
test.alertT(); 
test.setT('hello, world'); 
test.alertT(); 

La syntaxe que vous utilisez est le modèle habituel pour créer quelque chose qui agit comme une variable privée dans JS.

+0

Je ne pouvais pas comprendre ce que statichippo demandait jusqu'à ce que j'ai vu votre réponse. Je suppose qu'il pensait que "ceci" était une référence à la portée contenant les variables de fermeture? Bonne explication. Mon conseil est de ne pas utiliser "ceci" sauf si vous écrivez OO "class like" code où "this" fait référence à l'objet manipulé, auquel cet exemple pourrait facilement être changé. Mais comme vous l'avez mentionné, ce module patttern vous donne des variables vraiment privées (ce qui rend plus difficile le débogage) –

1

t ne fait pas partie de la portée de 'this'. t est une variable locale à la méthode. Donc, quelque part, vous devez faire

this.t = whatever 

...

est ici un exemple concret de la vie d'une application que je suis en train d'écrire

var scope = this; 

cells.forEach(function(cell, index) { 
      var given = cell.get('given'); 

      var value = cell.get('value'), 
          valueAsString = '%@'.fmt(value); 


      var rowValues = scope.getRowForIndex(index); 
      ... 
} 

le champ intérieur de la fonction forEach est la portée de la tableau 'cellules' sur lequel je suis itératif. Puisque je veux faire des choses sur la portée d'appel, j'utilise une fermeture ...

+0

True. Mais cela peut aussi être une mauvaise idée. Si "this" est l'objet global dans cette méthode, une variable globale sera créée. – Jakob

+0

mais puisqu'il s'agit d'une fermeture, si je me réfère simplement à t, j'obtiens le t fermé car la fonction elle-même ne contient aucune variable t. Je suis vraiment intéressé de savoir comment je peux me référer explicitement à la méthode fermée. – hackerhasid

+0

@jakob, absolument. Semble OP essaie juste de comprendre comment la portée fonctionne dans les fermetures cependant, et ce n'est qu'un exemple – hvgotcodes

0

en C# et Java, on peut faire quelque chose comme ceci:

public class MyClass { 
    private int x; 

    public void DoSomething(int x) { 
     int a = this.x; 
     int b = x; 
    } 
} 

Les variables a et b auront des valeurs de différentes années x, puisque l'on est de la classe x un celui-ci est les méthodes x. Maintenant, imaginez si vous ne pouviez pas utiliser this pour faire explicitement référence à x de la classe. Ensuite, vous devez faire ce qui suit:

public class MyClass { 
    private int classX; 

    public void DoSomething(int x) { 
     int a = classX; 
     int b = x; 
    } 
} 

Voilà la situation que vous avez en JavaScript, à peu près.Au moins dans la situation que vous décrivez. En utilisant les méthodes apply et call vous pouvez changer le contexte dans lequel une fonction est exécutée, mais vous ne pouvez jamais distinguer les variables avec les noms de sames mais les portées différentes. Vous devrez simplement utiliser des noms différents pour cela.