Tatsächlich ist dies ein Klischee. Es gibt viele Artikel darüber. Eigentlich dachte ich, ich hätte es herausgefunden, aber gestern hatte ich während des Projekts immer noch ein wenig Zweifel. Ich dachte über einen detaillierten Artikel nach, den ich in JavaScript Weekly gesammelt und gelesen hatte (es gab später einen Link, und die chinesische Übersetzung auf Seltenen Erden wurde beigefügt) und ein weiterer Artikel, der von einem Senior empfohlen wurde, also habe ich sie mir angesehen und mein Verständnis dafür hat sich tatsächlich ein wenig verbessert.
'Dies' in JavaScript ist dynamisch und wird bestimmt, wenn die Funktion ausgeführt wird, nicht wenn die Funktion deklariert wird. Alle Funktionen können "dies" aufrufen, was keine Rolle spielt, wenn die Funktion zu einem Objekt gehört. In diesem Zusammenhang gibt es hauptsächlich vier Situationen.
1. Die als Objekt verwendete Methode wird aufgerufen
Wenn die Funktion eine Methode ist, die als Objekt angesehen wird, weist diese der Funktion auf das Objekt hin.
var John = {FirstName: "John"} Funktion func () {alert (this.firstname + ": hi!")} John.sayhi = func John.sayhi () // this = JohnHier ist etwas erwähnenswert. Wenn die Methode eines Objekts herausgenommen und einer Variablen zugeordnet ist, wird die Methode zu einem Funktionsauslöser, und dies zeigt auf Fenster oder Unterfind (Strict -Modus).
2. Rufen Sie innerhalb der Funktion auf
Wenn diese Funktion dies hat, bedeutet dies tatsächlich, dass sie als Methode bezeichnet wird. Das Aufrufen zwischen den beiden entspricht der Behandlung als Fensterobjekt. Dies zeigt auf das Fenster. Es ist erwähnenswert, dass ES5 tatsächlich festlegt, dass dies = undefiniert ist und nur Browser nach der alten Methode (ich teste es in der neuesten Version von Chrome, Safari und Firefox, das alle Punkte (201607)) und strikte Modus verwendet, um auf Undepined unter Firefox zu verweisen.
func () function func () {alert (this) // [Objektfenster] oder [Objekt global] oder Art von ..}Um dies zu bestehen, sollte () zuvor ein Referenztyp sein, ähnlich wie obj.a oder obj ['a'] und nichts anderes sein kann.
Hier gibt es auch eine kleine Grube. Wenn in der Methode des Objekts eine Funktion vorhanden ist, wird die Funktion tatsächlich als Funktionsmodus ausgelöst, sodass diese Standards für das Fenster (undefiniert im strengen Modus). Die Lösung besteht darin, dies an die Funktion zu binden.
var numbers = {numbera: 5, numberb: 10, sum: function () {console.log (this === numbers); // => True Function Calculate () {// Dies ist ein Fenster oder nicht definiert in strict mody console.log (this === Zahlen); // => false return this.numbera + this.numberb; } return calculate (); }}; numbers.sum (); // => nan oder tiltError in strict modus var numbers = {numbera: 5, numberb: 10, sum: function () {console.log (this === number); // => True Function Calculate () {console.log (this === Zahlen); // => true return this.numbera + this.numberb; } // verwenden Sie die .call () -Methode, um den Kontextrendite zu ändern. }}; numbers.sum (); // => 153. Rufen Sie neu ein
Eine Variable, die auf ein Objekt verweist, speichert tatsächlich einen Verweis auf das Objekt, dh die Variable speichert tatsächlich einen Zeiger auf die realen Daten.
Bei der Verwendung des neuen Schlüsselworts erfolgt diese Änderung tatsächlich die folgenden Schritte:
Erstellen Sie dies = {}.
Dies kann während der Ausführung neuer Neue geändert werden, und dann werden Attribute und Methoden hinzugefügt.
Gibt dies zurück.
Funktion Animal (Name) {this.name = name this.canwalk = true} var Animal = New Animal ("Beastie") Alert (Animal.Name)Es ist zu beachten, dass, wenn der Konstruktor ein Objekt zurückgibt, dies auf das zurückgegebene Objekt zeigt;
Funktion Animal () {this.name = 'Mousie'; this.age = '18'; Return {Name: 'Godzilla'} // <- wird zurückgegeben} var Animal = new Animal () console.log (Animal.Name) // Godzilla console.log (Animal.age) // undefiniertEs ist wichtig zu beachten, dass es nicht vergessen wird, neue zu verwenden, sonst wird eine neue Funktion nicht erstellt. Stattdessen wird nur die Funktion ausgeführt, die einem Funktionsaufruf entspricht, und dies zeigt tatsächlich auf das Fenster
Funktionsfahrzeug (Typ, WheelsCount) {this.type = Typ; this.wheelsCount = WheelsCount; Gibt dies zurück;} // Funktion InvocationVar Car = Fahrzeug ('Car', 4); CAR.Type; // => 'Car' Car.WheelsCount // => 4 CAR === Fenster // => True4. Nennen Sie dies eindeutig, verwenden Sie Anrufe und bewerben Sie sich
Dies ist der am meisten von JavaScript inspirierte Ort.
Der folgende Code:
func.call(obj, arg1, arg2,...)
Der erste Parameter wird als Referenzobjekt davon verwendet, und der nachfolgende Parameter wird als Parameter der Funktion verwendet. Die Lösung besteht darin, Bind zu verwenden.
Funktion Animal (Typ, Beine) {this.type = Typ; this.Legs = Beine; this.loginfo = function () {console.log (this === mycat); // => true console.log (' + this.type +' hat ' + this.legs +' legs '); };} var mycat = new Animal ('cat', 4); // Protokolle "Die Katze hat 4 Beine" setTimeout (mycat.loginfo.bind (mycat), 1000); // setTimeout ?? var John = {FirstName: "John", Incident: "Smith"} Funktion func (a, b) {alert (this [a] + '' + this [b])} func.call (John, 'FirstName', 'Nachname') // "John Smith"Was das Anwendung betrifft, wird nur die Parameter im Quadrat des Arrays übergeben, und die anderen Teile sind wie folgt gleich:
func.call (John, 'FirstName', 'Nachname') func.apply (John, ['FirstName', 'Nachname'])
Sie können auch in der Klassenvererbung in ES5 verwendet werden, um den übergeordneten Konstruktor aufzurufen.
Funktionsläufer (Name) {console.log (diese Instanz von Kaninchen); // => true this.name = name; } function Rabbit (Name, Counlegs) {console.log (dieses Instanz von Kaninchen); // => true // indirekt aufgerufen, der übergeordnete Konstruktorläufer.call (this, Name); this.countegs = countlegs; } var myrabbit = neuer Kaninchen ('White Rabbit', 4); Myrabbit; // {Name: 'White Rabbit', Counlegs: 4}5..bind ()
Vergleichen Sie die Methoden .Apply () und .call (), die beide die Funktion sofort ausführen, während die Funktion .bind () eine neue Methode zurückgibt, die diese vorgegebene Bindung bindet und den Aufruf verzögern kann.
Die Funktion der .bind () -Methode besteht darin, eine neue Funktion zu erstellen. Der Kontext während der Ausführung ist der erste Parameter, der von .Bind () übergeben wurde und die die Erstellung einer Funktion mit dieser Voreinstellung ermöglicht.
var numbers = {Array: [3, 5, 10], getNumbers: function () {return this.Array; }}; // Erstellen Sie ein gebundenes Funktionsvar bigTGEnumbers = numbers.getNumbers.bind (numbers); bigTetNumbers (); // => [3, 5, 10] // Methode aus ObjectVar SimpleGetNumbers = number.getNumbers; SimpleGetNumbers (); // => undefiniert oder wirft einen Fehler im strengen Modus ausBei Verwendung von .bind () sollten Sie beachten, dass .bind () eine ewige Kontextkette erstellt und nicht verändert ist. Auch wenn eine Bindungsfunktion .call () oder .Apply () verwendet, um in andere verschiedene Kontexte zu gelangen, ändert sie den Kontext ihrer vorherigen Verbindung nicht und das Wiederherstellen spielt keine Rolle.
Nur wenn der Konstruktor aufgerufen wird, kann die Bindungsfunktion den Kontext ändern, dies ist jedoch kein besonders empfohlener Ansatz.
6. Pfeilfunktion
Die Pfeilfunktion erzeugt nicht den Kontext ihrer eigenen Ausführung, so dass dies von der externen Funktion abhängt, die zum Zeitpunkt der Definition definiert ist.
Pfeilfunktionen können nicht nach der Bindung des Kontextes geändert werden, auch wenn die Kontextänderungsmethode verwendet wird:
var numbers = [1, 2]; (function () {var get = () => {console.log (this === numbers); // => true return this;}; console.log (this === number); // => true get (); // => [1, 2] // Arrow -Funktionen verwenden .Apply () und .call (). // => [1, 2] // bindg.bind ([0]) ();Dies liegt daran, dass die Pfeilfunktion einen statischen Kontext hat und sich aufgrund unterschiedlicher Anrufe nicht ändert. Verwenden Sie daher keine Pfeilfunktionen, um Methoden zu definieren
Funktionsperiode (Stunden, Minuten) {this.hours = Stunden; this.minutes = Minuten; } Periode.Prototype.Format = () => {console.log (this === Fenster); // => true return this. stunden + 'Stunden und' + this.minutes + 'minute'; }; var Walkperiod = neue Periode (2, 30); Walkperiod.Format (); // => 'undefinierte Stunden und undefinierte Minuten'beziehen sich auf
Vier Düfte von "This"
Sanfte Erläuterung von 'This' Keyword in JavaScript
JavaScript Dieses Geheimnis (Übersetzung)
Es wird sehr empfohlen, dass Schüler, die es nicht verstehen. Schauen Sie sich die oben genannten Artikel an, die dritte ist die Übersetzung der zweiten. Wenn Sie Fragen dazu haben, können Sie gerne gemeinsam diskutieren, kommunizieren und das Denken fördern und gemeinsam Fortschritte machen.