"Diese" Variable einfach einstellen?

139

Ich habe ein ziemlich gutes Verständnis von Javascript, außer dass ich keine gute Möglichkeit finden kann, die Variable "this" festzulegen. Erwägen:

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 nervig ... Ich habe versucht, eine anonyme Funktion zu binden, die ich für schön und klug hielt, 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.

Natürlich ist die Übergabe der Variablen an myFunction eine Option ... aber darum geht es bei dieser Frage nicht.

Vielen Dank.

Erik Philips
quelle

Antworten:

221

Es gibt zwei für alle Funktionen in JavaScript definiert Methoden, call()und apply(). Die Funktionssyntax sieht folgendermaßen aus:

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

Was diese Funktionen zu tun ist , um die Funktion rufen sie aufgerufen wurden, den Wert des Zuordnung Objektparameter zu dieser .

var myFunction = function(){
    alert(this.foo_variable);
}
myFunction.call( document.body );
Für dein eigenes Wohl
quelle
3
Wenn Sie jQuery verwenden, können Sie es auch $.proxy(function, element)so verwenden, dass es bei jedem Aufruf dieser Funktion im Kontext des Elements steht. api.jquery.com/jquery.proxy
Trevin Avery
Eine andere nützliche Methode ist.bind()
Soroush Falahati
55

Ich denke du suchst call:

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

Dies ruft myFunctionmit thisset to auf obj.

Es gibt auch die etwas andere Methode apply, bei der die Funktionsparameter als Array verwendet werden:

myFunction.apply(obj, [arg1, arg2, ...]);
etw
quelle
1
Siehe Abschnitt 15.3.4.3, 15.3.4.4 und 10.1.8 in der ECMAScript-Sprachspezifikation: ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
einige
18

Wenn Sie den thisWert in einer Funktion speichern möchten, damit Sie ihn später nahtlos aufrufen können (z. B. wenn Sie nicht mehr auf diesen Wert zugreifen können), können bindSie dies (jedoch nicht in allen Browsern verfügbar):

var bound = func.bind(someThisValue);

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

bound(); // will call with someThisValue as 'this'
pimvdb
quelle
7
FYI bindist anscheinend in IE9 +, FF4 +, Safari 5.1.4+ und Chrome 7+ (Quelle) verfügbar . Sie können bind auch direkt für eine anonyme Funktion aufrufen:var myFunction = function(){ /* this = something */ }.bind(something);
Adam
1

Meine Suche nach dem Binden thishat mich hierher gebracht, sodass ich meine Ergebnisse veröffentliche: In 'ECMAScript 2015' können wir dies auch lexikalisch mit Pfeilfunktionen auf einstellen.

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

Anstatt:

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();
Daniel Sokolowski
quelle
0

Festlegen des thisSchlüsselworts in Javascript.

Javascript verfügt über 3 integrierte Methoden zum thisbequemen Festlegen des Schlüsselworts. Sie befinden sich alle auf dem Function.prototypeObjekt, sodass jede Funktion sie verwenden kann (da jede Funktion über die prototypische Vererbung von diesem Prototyp erbt). Diese Funktionen sind die folgenden:

  1. Function.prototype.call(): Diese Funktion verwendet das Objekt, das Sie thisals erstes Argument verwenden möchten . Der Rest der Argumente sind dann die jeweiligen Argumente der aufgerufenen Funktion.
  2. Function.prototype.apply(): Diese Funktion verwendet das Objekt, das Sie thisals erstes Argument verwenden möchten . Dann ist das zweite Argument ein Array, das die Werte der Argumente der aufgerufenen Funktion enthält (erstes Element des Arrays ist erstes Argument der Funktion, zweites Argument des Arrays ist zweites Argument der Funktion usw.).
  3. Function.prototype.bind(): Diese Funktion gibt eine neue Funktion zurück, die einen anderen Wert von hat this. Es nimmt das Objekt, das Sie als thisWert festlegen möchten, als erstes Argument und gibt dann ein neues Funktionsobjekt zurück.

Unterschied zwischen call / apply und bind:

  • callund applyähneln sich darin, dass sie die Funktion sofort aufrufen (mit einem vordefinierten Wert von this)
  • bindunterscheidet sich von callund applyin der Tatsache, dass diese Funktion eine neue Funktion mit einer anderen Bindung des thisWerts zurückgibt .

Beispiele:

const thisObj = {
  prop1: 1,
  prop2: 2,
};

function myFunc(arg1, arg2) {
  console.log(this.prop1, this.prop2);
  console.log(arg1, arg2);
}

// first arg this obj, other arguments are the  
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');

// first arg this obj, other argument is an array which  
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);


// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);

// now we can call the function like a normal function 
newMyFunc('first', 'second');

Willem van der Veen
quelle