391 Stimmen

Was bedeutet 'var that = this;' in JavaScript?

In einer JavaScript-Datei habe ich gesehen:

function Somefunction(){
   var that = this; 
   ... 
}

Was ist der Zweck der Erklärung von that und die Zuweisung this dies zu tun?

520voto

lonesomeday Punkte 224087

Ich werde diese Antwort mit einer Illustration beginnen:

var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
    // this is a reference to the element clicked on

    var that = this;

    colours.forEach(function() {
        // this is undefined
        // that is a reference to the element clicked on
    });
});

In meiner Antwort wurde dies ursprünglich mit jQuery demonstriert, das sich nur sehr geringfügig unterscheidet:

$('#element').click(function(){
    // this is a reference to the element clicked on

    var that = this;

    $('.elements').each(function(){
        // this is a reference to the current element in the loop
        // that is still a reference to the element clicked on
    });
});

Denn this häufig ändert, wenn Sie den Bereich durch den Aufruf einer neuen Funktion ändern, können Sie nicht auf den ursprünglichen Wert zugreifen, indem Sie ihn verwenden. Das Aliasing auf that können Sie immer noch auf den ursprünglichen Wert von this .

Mir persönlich missfällt die Verwendung von that als Alias. Es ist selten offensichtlich, worauf er sich bezieht, insbesondere wenn die Funktionen länger als ein paar Zeilen sind. I toujours einen aussagekräftigeren Alias verwenden. In meinen obigen Beispielen würde ich wahrscheinlich verwenden clickedEl .

117voto

El Ronnoco Punkte 11443

Von Crockford

Wir machen aus Konvention eine private dass variabel. Diese wird verwendet, um das Objekt für die privaten Methoden verfügbar zu machen. Dies ist ein Workaround für einen Fehler in der ECMAScript-Sprachenspezifikation Spezifikation, der dazu führt, dass ce t für innere Funktionen falsch gesetzt.

JS-Fiedel

function usesThis(name) {
    this.myName = name;

    function returnMe() {
        return this;        //scope is lost because of the inner function
    }

    return {
        returnMe : returnMe
    }
}

function usesThat(name) {
    var that = this;
    this.myName = name;

    function returnMe() {
        return that;            //scope is baked in with 'that' to the "class"
    }

    return {
        returnMe : returnMe
    }
}

var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
      "UsesThis thinks it's called " + usesthis.returnMe().myName);

Das alarmiert...

UsesThat denkt, es heißt Dave

UsesThis denkt, es heißt undefiniert

91voto

Waylon Flinn Punkte 19361

Dies ist ein Hack, der dafür sorgt, dass innere Funktionen (Funktionen, die innerhalb anderer Funktionen definiert sind) besser funktionieren als sie sollten. In Javascript, wenn Sie eine Funktion innerhalb einer anderen definieren this wird automatisch auf den globalen Bereich gesetzt. Dies kann verwirrend sein, weil man erwartet this den gleichen Wert wie in der äußeren Funktion haben soll.

var car = {};
car.starter = {};

car.start = function(){
    var that = this;

    // you can access car.starter inside this method with 'this'
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to the global scope
        // 'this.starter' is undefined, so we use 'that' instead.
        that.starter.active = true;

        // you could also use car.starter, but using 'that' gives
        // us more consistency and flexibility
    };

    activateStarter();

};

Dies ist insbesondere ein Problem, wenn Sie eine Funktion als Methode eines Objekts erstellen (wie car.start im Beispiel), dann erstellen Sie eine Funktion innerhalb dieser Methode (wie activateStarter ). Bei der Top-Level-Methode this zeigt auf das Objekt, von dem es eine Methode ist (in diesem Fall, car ), sondern in der inneren Funktion this verweist nun auf den globalen Bereich. Das ist ein Problem.

Erstellen einer Variablen zu verwenden, durch Konvention in beiden Bereichen ist eine Lösung für dieses sehr allgemeine Problem mit Javascript (obwohl es in Jquery-Funktionen nützlich ist, auch). Dies ist der Grund, warum der sehr allgemein klingende Name that verwendet wird. Es ist eine leicht erkennbare Konvention zur Überwindung eines Mangels in der Sprache.

Wie El Ronnoco andeutet Douglas Crockford hält dies für eine gute Idee.

11voto

Adela Punkte 101

Die Verwendung von that ist nicht wirklich notwendig, wenn Sie eine Umgehung durch die Verwendung von call() o apply() :

var car = {};
car.starter = {};

car.start = function(){
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to our main object
        this.starter.active = true;
    };

    activateStarter.apply(this);
};

3voto

Ahmad Ajmi Punkte 6427

Manchmal this kann sich auf einen anderen Bereich beziehen und auf etwas anderes verweisen, z.B. wenn Sie eine Konstruktormethode innerhalb eines DOM-Ereignisses aufrufen wollen, in diesem Fall this verweist auf das DOM-Element und nicht auf das erstellte Objekt.

HTML

<button id="button">Alert Name</button>

JS

var Person = function(name) {
  this.name = name;
  var that = this;
  this.sayHi = function() {
    alert(that.name);
  };
};

var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad

Demo

Die obige Lösung wird die this a that dann können wir und auf die Eigenschaft name innerhalb der sayHi Methode von that so dass dies ohne Probleme innerhalb des DOM-Aufrufs aufgerufen werden kann.

Eine andere Lösung ist die Zuweisung eines leeren that Objekt und fügen ihm Eigenschaften und Methoden hinzu und geben es dann zurück. Aber mit dieser Lösung haben Sie die prototype des Konstruktors.

var Person = function(name) {
  var that = {};
  that.name = name;
  that.sayHi = function() {
    alert(that.name);
  };
  return that;
};

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X