2009-01-19 5 views
124

J'ai une bonne compréhension de Javascript, sauf que je n'arrive pas à trouver une bonne façon de définir la variable "this". Considérez:Définir facilement cette variable?

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body; //using body as example object 
someObj.foo_variable = "hi"; //set foo_variable so it alerts 

var old_fn = someObj.fn; //store old value 
someObj.fn = myFunction; //bind to someObj so "this" keyword works 
someObj.fn();    
someObj.fn = old_fn;  //restore old value 

Y at-il un moyen de le faire sans les 4 dernières lignes? Il est plutôt ennuyeux ... Je l'ai essayé lier une fonction anonyme, que je pensais était belle et intelligente, mais en vain:

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body;  //using body as example object 
someObj.foo_variable = "hi";  //set foo_variable so it alerts 
someObj.(function(){ fn(); })(); //fail. 

De toute évidence, passer la variable dans maFonction est une option ... mais c'est pas le point de cette question.

Merci.

Répondre

207

Il existe deux méthodes définies pour toutes les fonctions JavaScript, call() et apply(). La syntaxe de la fonction ressemble:

call(/* object */, /* arguments... */); 
apply(/* object */, /* arguments[] */); 

Ce que ces fonctions font est d'appeler la fonction qu'ils ont été invoquées sur, affectant la valeur du paramètre d'objet à ce .

var myFunction = function(){ 
    alert(this.foo_variable); 
} 
myFunction.call(document.body); 
+3

De plus, si vous utilisez jQuery, vous pouvez utiliser '$ .proxy (function, element)' pour que chaque fois que cette fonction n est appelé, ce sera dans le contexte de l'élément. http://api.jquery.com/jquery.proxy/ –

54

Je pense que vous êtes à la recherche call:

myFunction.call(obj, arg1, arg2, ...); 

Cela appelle myFunction avec this ensemble à obj.

Il existe également la méthode légèrement différente apply, qui prend les paramètres de la fonction sous forme de tableau:

myFunction.apply(obj, [arg1, arg2, ...]); 
+1

Voir section 15.3.4.3, 15.3.4.4 et 10.1.8 dans ECMAScript Language Specification: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

Si vous voulez « magasin » la valeur this à une fonction de sorte que vous pouvez l'appeler de façon transparente plus tard (par exemple, lorsque vous n'avez pas accès à cette valeur plus), vous pouvez bind (non disponible dans tous les navigateurs cependant):

var bound = func.bind(someThisValue); 

// ... later on, where someThisValue is not available anymore 

bound(); // will call with someThisValue as 'this' 
+5

FYI 'bind' est apparemment disponible dans IE9 +, FF4 +, Safari 5.1.4+ et Chrome 7+ [(source)] (http: //kangax.github. io/es5-compat-table/# Fonction.prototype.bind). Vous pouvez également appeler bind directement sur une fonction anonyme: 'var myFunction = function() {/ * this = quelque chose * /} .bind (quelque chose);' – Adam

0

Ma recherche sur la façon de lier this m'a amené ici, donc je suis annonce mes résultats: dans « ECMAScript 2015 », nous pouvons également définir ce à l'aide de fonctions lexicalement la flèche.

Voir: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Au lieu de:

function Person() { 
    setInterval(function growUp() { 
    // The callback refers to the `self` variable of which 
    // the value is the expected object. 
    this.age++; 
    }.bind(this), 1000); 
} 

Nous pouvons maintenant faire:

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person(); 
Questions connexes