2010-08-25 6 views
8

Dans mes objets javascript je me suis trouvé écrit ceci:Y at-il une meilleure méthode que de définir une variable à cela?

this_object = this; 

Il semble que c'est la seule façon de passer des variables membres aux fonctions externes ...

google.maps.event.addListener(this.marker, 'click', function() { 
    this.info_window.setContent('Chicago marker'); 
    this.info_window.open(this.map,this.marker); 
}); 

Cela ne fonctionne pas, je copier l'objet dans une variable membre et passer le nouvel objet (et remplacer tous les this par this_object)

Cela semble moche. Existe-t-il un moyen «meilleur» ou «plus propre» ou s'agit-il de ma seule option?

+0

Voir aussi: ['cet' objet n'est pas accessible dans les fonctions JavaScript privées sans piratage?] (Http://stackoverflow.com/questions/3274387/this-object-cant-be-accessed-in- private-javascript-functions-without-a-hack) – CMS

Répondre

5

Bien sûr, il existe une meilleure méthode. Cela implique de créer une fonction dont le contexte this est déjà lié à un objet particulier.

Pour que le contexte this fasse référence à l'objet actuel, appelez la méthode bind() sur la fonction et transmettez le contexte requis en tant que paramètre.

google.maps.event.addListener(this.marker, 'click', function() { 
    this.info_window.setContent('Chicago marker'); 
    this.info_window.open(this.map,this.marker); 
}.bind(this)); // <-- notice we're calling bind() on the function itself 

Ce fait maintenant partie de la norme ECMAScript, et si un navigateur ne met pas en œuvre en mode natif, il est facile de le faire vous-mêmes.

if (!Function.prototype.bind) { 
    Function.prototype.bind = function() { 
     var fn = this, 
      args = Array.prototype.slice.call(arguments), 
      object = args.shift(); 

     return function() { 
      return fn.apply(
       object, args.concat(Array.prototype.slice.call(arguments)) 
      ); 
     }; 
    }; 
} 

Voir tous questions and answers sur le SO lié à cela.

+0

cela ressemble à son un couple de crans au-dessus de mon javascript paygrade, mais je vais essayer de l'absorber. merci – Galen

+0

Cela a l'inconvénient d'introduire un appel de fonction supplémentaire, mais +1 néanmoins. –

4

C'est en fait un modèle assez commun lorsqu'il s'agit de JavaScript pour stocker une référence de this dans une variable locale, c'est-à-dire var myThing=this;. Les fonctions de rappel ont accès aux variables locales définies dans leur portée. Toutes les variables définies dans les fonctions contenant sont accessibles.

0

J'ai déjà vu le modèle (avec la variable en question qui est appelée), donc je suppose qu'il s'agit bien d'un modèle javascript courant qui n'a pas seulement une solution plus propre.

0

Je ne suis pas certain que cela vous aidera quel que soit le scénario auquel vous faites face, mais j'ai trouvé que l'utilitaire d'événements personnalisés de YUI fonctionnait bien avec les problèmes de portée avec ceci et les fermetures. C'est un modèle axé sur les événements, et une façon de penser légèrement différente, mais il pourrait être utile de l'explorer au moins.

http://developer.yahoo.com/yui/event/#customevent

1

Vous trouverez ce morceau de code assez fréquent dans les nombreuses bibliothèques et projets:

function someFunction() { 
    var that = this; 

    //.... 
} 

Par exemple, considérons cette fonction:

function container(param) { 

    function dec() { 
     if (secret > 0) { 
      secret -= 1; 
      return true; 
     } else { 
      return false; 
     } 
    } 

    this.member = param; 
    var secret = 3; 
    var that = this; 

    return function() { 
     if (dec()) { 
      return that.member + " " + secret; 
     } else { 
      return null; 
     } 
    }; 
} 

var c = container("foo"); 
alert(c()); // "foo 2"; 
alert(c()); // "foo 1"; 
alert(c()); // "foo 0"; 
alert(c()); // null; 

En savoir plus here.

Questions connexes