Heim  >  Artikel  >  Web-Frontend  >  Können Sie das Zeigeproblem von JS verstehen? Schauen Sie sich diesen Artikel an

Können Sie das Zeigeproblem von JS verstehen? Schauen Sie sich diesen Artikel an

青灯夜游
青灯夜游nach vorne
2022-03-25 11:05:521984Durchsuche

Können Sie das Zeigeproblem von JavaScript verstehen? Der folgende Artikel wird mit Ihnen über dieses lästige Zeigeproblem sprechen. Ich hoffe, er wird Ihnen helfen!

Können Sie das Zeigeproblem von JS verstehen? Schauen Sie sich diesen Artikel an

Das Zeigen von diesem

In den verschiedenen Einführungen haben wir gesehen, wie man die Zeigemethoden von diesem bestimmen kann: „Dies zeigt letztendlich auf das Objekt, das es aufruft.“ Dieser Satz wird als Kern angesehen , Aber angesichts der unterschiedlichen Situationen neigen wir dazu, verwirrt zu sein. Basierend auf meinem Verständnis verschiedener Situationen habe ich einen Satz vorgeschlagen „Pfeile, Timing und Struktur, besondere Aufmerksamkeit in besonderen Situationen, normale Aufrufe, sich die Punktnummer anzusehen, die späteren Punkte nicht nach vorne zu schauen, und dann basierend auf der Beurteilung.“ nach dem nächstgelegenen Prinzip, und das letzte verbleibende Ding ist das Fenster „. [Verwandte Empfehlungen: Javascript-Lern-Tutorial]

Pfeilfunktion

Die Pfeilfunktion selbst hat dies nicht, daher gibt es diese Änderung nicht. Sie erfasst das Äußere mithilfe von

var name = "windowsName";
var a = {
    name: "Cherry",
    fn() {
      setTimeout(()=>{
        console.log(this.name); 
      },0)
    }
}

a.fn() //Cherry

Analyse: Zuerst Objekt a ruft die fn-Funktion auf, also zeigt diese der fn-Funktion auf Objekt a, und dann erfasst der Pfeil das äußere this, dann ist es nicht dieses in setTimeout, sondern dieses der fn-Funktion, also erhalten wir schließlich den Namen in Objekt a

timer

Für die Rückruffunktion innerhalb der Verzögerungsfunktion zeigt dies auf das globale Objektfenster

var name = "windowsName";
var a = {
    name: "Cherry",
    fn() {
      setTimeout(function (){
        console.log(this.name); 
      },0)
    }
}

a.fn() //windowsName

Analyse: Zuerst ruft Objekt a die fn-Funktion auf, und dann ist die Rückruffunktion in setTimeout hier eine anonyme Funktion , das ist eine gewöhnliche Funktion, dann ist dies eine anonyme Funktion, die auf das Fenster zeigt this in der anonymen Funktion zeigt auf window, aber verwenden Sie bind, um die anonyme Funktion zu ändern. This verweist auf Objekt b, sodass der Nachname im Objekt b

this im Konstruktor auf das erstellte Instanzobjekt verweist ,Hinweis: Wenn ein Objekt im Konstruktor zurückgegeben wird, wird es beim Erstellen nicht erstellt. Es wird ein neues Instanzobjekt geben, aber dieses zurückgegebene Objekt

var name = "windowsName";
var b={
  name: "setTimeoutName"
}
var a = {
    name: "Cherry",
    fn() {
      setTimeout((function (){
        console.log(this.name); 
      }).bind(b),0)
    }
}

a.fn() //setTimeoutName

Analyse: Hier erstellen wir das Instanzobjekt a über den Konstruktor, was dem Öffnen eines neuen Ortes und dem Kopieren des Inhalts des Konstruktors entspricht. Zu diesem Zeitpunkt gibt es ein Objekt a. Das Ändern des Inhalts in Objekt a hat keine Auswirkungen auf den Konstruktor

Beurteilung der Punktzahl

Verwenden Sie ., um den Punkt zu beurteilen und dem Prinzip der Nähe zu folgen

function fn(){
  this.age = 37;
}

var a = new fn();
console.log(a.age); // 37
a.age = 38;
console.log(fn); // { this.age = 37; }
console.log(a.age); // 38

Analyse: Objekt a ruft die fn-Funktion von Objekt b auf. Es gibt zwei . vor der fn-Funktion, also ist das nächstgelegene Objekt b, also zeigt diese der fn-Funktion auf Objekt b, und das letzte, was sie erhält, ist das Alter von Objekt b

var a = {
  age:10,
  b: {
      age:12,
      fn(){
          console.log(this.age); 
      }
  }
}
a.b.fn(); //12
Analyse: Objekt a ruft die fn-Funktion von Objekt b auf und verwendet dann bind, um die Richtung zu ändern. Zu diesem Zeitpunkt gibt es . vor und nach fn, unabhängig vom vorherigen .. Schauen Sie sich einfach die Rückseite an, und dann ändert die letzte Bindung diesen Punkt in c, dann zeigt dieser Punkt der fn-Funktion auf Objekt c, und Sie erhalten das Alter von Objekt c

Übung

.判断this指向,遵循就近原则

var a = {
  age:10,
  b: {
      age:12,
      fn(){
          console.log(this.age); //undefined
      }
  }
}
var c = {
  age:20,
}

var d = {
  age:30,
}
a.b.fn.bind(c).bind(d)(); //20

解析:对象a调用对象b的fn函数,fn函数前面有两个.,那么最近的是对象b,所以fn函数的this指向的就是对象b,最后拿到的就是对象b的age

function outerFunc() {
   console.log(this) // { x: 1 }
   function func() {
    console.log(this) // Window 
   }
   func()
} 

outerFunc.bind({ x: 1 })()

解析:对象a调用对象b的fn函数然后使用bind改变this的指向,这时候fn前后前后都有.,不看前面的.,只用看后面的,然后最近的bind改变this指向为c,那么此时fn函数的this指向的就是对象c,拿到的就是对象c的age

练习

obj = {
  func() {
    const arrowFunc = () => {
      console.log(this._name)
    }

    return arrowFunc
  },

  _name: "obj",
}

obj.func()() //obj

func = obj.func
func()()  //undefined

obj.func.bind({ _name: "newObj" })()() //newObj

obj.func.bind()()() //undefined

obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })() //bindObj
rrreee

apply、call、bind

使用 apply、call、bind 函数可以改变this的指向,上面this的例子中使用到

区别

thisArg , [ argsArray] call(thisArg, arg1, arg2, ...)

apply和call函数区别在于this后面传入的参数,apply中传的是一个数组,而call中传入的是展开的参数

bind(thisArg[, arg1[, arg2[, ...]]])()

  • 然后bind函数创建的是一个新的函数,需要手动去调用
  • 这个新函数的 this 被指定为 bind()
  • rrreeerrreee

apply, call, bind

Verwenden Sie die Funktionen apply, call, bind, um den Zeiger davon zu ändern. Im obigen Beispiel wird der Unterschied

thisArg, [ argsArray] call(thisArg, arg1, arg2, ...)

Der Unterschied zwischen apply- und call-Funktionen liegt in den Parametern, die danach übergeben werden. Bei apply wird ein Array übergeben , während des Aufrufs werden die erweiterten Parameter übergeben

bind(thisArg[, arg1[, arg2[, ...]]])()

Das obige ist der detaillierte Inhalt vonKönnen Sie das Zeigeproblem von JS verstehen? Schauen Sie sich diesen Artikel an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen