溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中this指向問題的示例分析

發布時間:2021-04-16 10:34:40 來源:億速云 閱讀:136 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關JavaScript中this指向問題的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1. 箭頭函數

箭頭函數排在第一個是因為它的 this 不會被改變,所以只要當前函數是箭頭函數,那么就不用再看其他規則了。

箭頭函數的 this 是在創建它時外層 this 的指向。這里的重點有兩個:

  1. 創建箭頭函數時,就已經確定了它的 this 指向。

  2. 箭頭函數內的 this 指向外層的 this。

所以要知道箭頭函數的 this 就得先知道外層 this 的指向,需要繼續在外層應用七步口訣。

2. new

當使用 new 關鍵字調用函數時,函數中的 this 一定是 JS 創建的新對象。

讀者可能會有疑問,“如果使用 new 關鍵調用箭頭函數,是不是箭頭函數的 this 就會被修改呢?”。

我們在控制臺試一下。

func = () => {}
new func() // throw error

從控制臺中可以看出,箭頭函數不能當做構造函數,所以不能與 new 一起執行。

3. bind

bind 是指 Function.prototype.bind() 。

多次 bind 時只認第一次 bind 的值

易錯點

function func() {
  console.log(this)
}

func.bind(1).bind(2)() // 1

箭頭函數中 this 不會被修改


bind 與 new

易錯點

function func() {
  console.log(this, this.__proto__ === func.prototype)
}

boundFunc = func.bind(1)
new boundFunc() // Object true,口訣 2 優先

4. apply 和 call

apply() 和 call() 的第一個參數都是 this,區別在于通過 apply 調用時實參是放到數組中的,而通過 call 調用時實參是逗號分隔的。

箭頭函數中 this 不會被修改

易錯點

func = () => {
  // 這里 this 指向取決于外層 this,參考口訣 7 「不在函數里」
  console.log(this)
}

func.apply(1) // Window,口訣 1 優先

bind 函數中 this 不會被修改

易錯點

function func() {
  console.log(this)
}

boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口訣 3 優先

5. 歐比屆點(obj.)

function func() {
  console.log(this.x)
}

obj = { x: 1 }
obj.func = func
obj.func() // 1

這里就不用代碼例證箭頭函數和 bind 函數的優先級更高了,有興趣可自行嘗試吧。

6. 直接調用

在函數不滿足前面的場景,被直接調用時,this 將指向全局對象。在瀏覽器環境中全局對象是 Window,在 Node.js 環境中是 Global。

先來個簡單的例子。

function func() {
  console.log(this)
}

func() // Window

來一個復雜的例子,外層的 outerFunc 就起個迷惑目的。

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

  function func() {
    console.log(this) // Window
  }

  func()
}

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

7. 不在函數里

不在函數中的場景,可分為瀏覽器的 <script /> 標簽里,或 Node.js 的模塊文件里。

  1. 在 <script /> 標簽里,this 指向 Window。

  2. 在 Node.js 的模塊文件里,this 指向 Module 的默認導出對象,也就是 module.exports。

非嚴格模式

嚴格模式是在 ES5 提出的。在 ES5 規范之前,也就是非嚴格模式下,this 不能是 undefined 或 null。所以**在非嚴格模式下,通過上面七步口訣,如果得出 this 指向是 undefined 或 null,那么 this 會指向全局對象。**在瀏覽器環境中全局對象是 Window,在 Node.js 環境中是 Global。

例如下面的代碼,在非嚴格模式下,this 都指向全局對象。

function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()

非嚴格模式下執行結果為:

JavaScript中this指向問題的示例分析

在嚴格模式下,執行同樣的代碼進行對比。記住要一次性將所有代碼復制粘貼到控制臺中,才能運行在嚴格模式下(因為第一行 "use strict" 才會對后面的代碼生效)。

"use strict"

function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()

嚴格模式下執行結果為:

JavaScript中this指向問題的示例分析

七步口訣在嚴格模式下和非嚴格模式下都是完備的,只是在非嚴格模式下 null 或 undefined 會被轉換為全局對象。所以我沒有將這點列入口訣中。

做題復習

先背誦口訣再做題,“箭頭函數、new、bind、apply 和 call、歐比屆點(obj.)、直接調用、不在函數里”。

1. 下面代碼執行后,func.count 值為多少?

function func(num) {
  this.count++
}

func.count = 0
func(1)

答案

func.count 值為 0。

按照口訣,func() 調用時屬于第 6 類「直接調用」。在非嚴格模式下,this 指向全局對象。this 跟 func 一點關系都沒有,所以 func.count 保持不變。so easy。

2. 以下箭頭函數中 this 指向誰呢?

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

    return arrowFunc
  },

  _name: "obj",
}

obj.func()()

func = obj.func
func()()

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

obj.func.bind()()()

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

答案

// obj
// undefined
// newObj
// undefined
// bindObj

關于“JavaScript中this指向問題的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女