2009-01-19 16 views
124

Ich habe ein ziemlich gutes Verständnis von Javascript, außer dass ich nicht einen netten Weg finde, um die "this" Variable zu setzen. Betrachte:"Diese" Variable leicht einstellen?

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 

Gibt es eine Möglichkeit, dies ohne die letzten 4 Zeilen zu tun? Es ist ziemlich ärgerlich ... Ich habe versucht, eine anonyme Funktion zu binden, was ich dachte, war schön und klug, aber ohne Erfolg:

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. 

Offensichtlich die Variable in myFunction vorbei ist eine Option ... aber das ist nicht der Punkt dieser Frage.

Danke.

Antwort

207

Es gibt zwei für alle Funktionen in JavaScript definierten Methoden, call() und apply(). Die Syntax die Funktion wie folgt aussieht:

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

Was diese Funktionen zu tun ist, um die Funktion ruft sie aufgerufen wurden, den Wert der Objekt Parameter diese zuweisen.

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

Wenn Sie jQuery verwenden, können Sie auch '$ .proxy (function, element)' verwenden wann immer diese Funktion n heißt, es wird im Kontext von Element sein. http://api.jquery.com/jquery.proxy/ –

54

Ich glaube, Sie suchen call:

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

Dies erfordert myFunction mit this Set obj.

Es besteht auch die etwas andere Methode apply, die die Funktionsparameter als Array nimmt:

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

Siehe Abschnitt 15.3.4.3, 15.3.4.4 und 10.1.8 in ECMAScript Language Specification: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

Wenn Sie den this Wert auf eine Funktion zu ‚speichern‘ wollen, so dass Sie es später nahtlos aufrufen können (zB wenn Sie den Zugriff auf diesen Wert haben nicht mehr), können Sie bind es (nicht verfügbar obwohl in allen Browsern):

var bound = func.bind(someThisValue); 

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

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

FYI 'bind' ist offenbar in IE9 +, FF4 +, Safari 5.1.4+ und Chrome 7+ [(Quelle)] (http: // kangax.github. io/es5-compat-table/# Funktion.prototype.bind). Sie können bind auch direkt an einer anonymen Funktion aufrufen: 'var myFunction = function() {/ * this = etwas * /} .bind (etwas);' – Adam

0

Meine Suche, wie mich zu binden this hierher gebracht, damit ich meine Erkenntnisse bin Entsendung: in ‚ECMAScript 2015‘ können wir auch diese lexikalisch mit Pfeilfunktionen eingestellt.

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

Statt:

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); 
} 

Wir können jetzt tun:

function Person(){ 
    this.age = 0; 

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

var p = new Person();