一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語(yǔ)言 - JavaScript - js教程 - JavaScript中的this指向問題詳解

JavaScript中的this指向問題詳解

2022-03-03 17:02MoonBall js教程

這篇文章主要給大家介紹了關(guān)于JavaScript中this指向問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

相信我,只要記住本文的 7步口訣,就能徹底掌握 JS 中的 this 指向。

先念口訣:箭頭函數(shù)、new、bind、apply 和 call、歐比屆點(diǎn)(obj.)、直接調(diào)用、不在函數(shù)里。

按照口訣的順序,只要滿足前面某個(gè)場(chǎng)景,就可以確定 this 指向了。

接下來按照口訣順序?qū)λ鼈冞M(jìn)行詳解,文中示例代碼都運(yùn)行在 Chrome 的 Console 控制臺(tái)中。

文末有精心準(zhǔn)備的練習(xí)題,用于檢驗(yàn)學(xué)習(xí)成果,別忘了試試~

1. 箭頭函數(shù)

箭頭函數(shù)排在第一個(gè)是因?yàn)樗?this 不會(huì)被改變,所以只要當(dāng)前函數(shù)是箭頭函數(shù),那么就不用再看其他規(guī)則了。

箭頭函數(shù)的 this 是在創(chuàng)建它時(shí)外層 this 的指向。這里的重點(diǎn)有兩個(gè):

  1. 創(chuàng)建箭頭函數(shù)時(shí),就已經(jīng)確定了它的 this 指向。
  2. 箭頭函數(shù)內(nèi)的 this 指向外層的 this。

所以要知道箭頭函數(shù)的 this 就得先知道外層 this 的指向,需要繼續(xù)在外層應(yīng)用七步口訣。

2. new

當(dāng)使用 new 關(guān)鍵字調(diào)用函數(shù)時(shí),函數(shù)中的 this 一定是 JS 創(chuàng)建的新對(duì)象。

讀者可能會(huì)有疑問,“如果使用 new 關(guān)鍵調(diào)用箭頭函數(shù),是不是箭頭函數(shù)的 this 就會(huì)被修改呢?”。

我們?cè)诳刂婆_(tái)試一下。

?
1
2
func = () => {}
new func() // throw error

從控制臺(tái)中可以看出,箭頭函數(shù)不能當(dāng)做構(gòu)造函數(shù),所以不能與 new 一起執(zhí)行。

3. bind

bind 是指 Function.prototype.bind() 。

多次 bind 時(shí)只認(rèn)第一次 bind 的值

易錯(cuò)點(diǎn)

?
1
2
3
4
5
function func() {
  console.log(this)
}
 
func.bind(1).bind(2)() // 1

箭頭函數(shù)中 this 不會(huì)被修改

?
1
 

bind 與 new

易錯(cuò)點(diǎn)

?
1
2
3
4
5
6
function func() {
  console.log(this, this.__proto__ === func.prototype)
}
 
boundFunc = func.bind(1)
new boundFunc() // Object true,口訣 2 優(yōu)先

4. apply 和 call

apply() 和 call() 的第一個(gè)參數(shù)都是 this,區(qū)別在于通過 apply 調(diào)用時(shí)實(shí)參是放到數(shù)組中的,而通過 call 調(diào)用時(shí)實(shí)參是逗號(hào)分隔的。

箭頭函數(shù)中 this 不會(huì)被修改

易錯(cuò)點(diǎn)

?
1
2
3
4
5
6
func = () => {
  // 這里 this 指向取決于外層 this,參考口訣 7 「不在函數(shù)里」
  console.log(this)
}
 
func.apply(1) // Window,口訣 1 優(yōu)先

bind 函數(shù)中 this 不會(huì)被修改

易錯(cuò)點(diǎn)

?
1
2
3
4
5
6
function func() {
  console.log(this)
}
 
boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口訣 3 優(yōu)先

5. 歐比屆點(diǎn)(obj.)

?
1
2
3
4
5
6
7
function func() {
  console.log(this.x)
}
 
obj = { x: 1 }
obj.func = func
obj.func() // 1

這里就不用代碼例證箭頭函數(shù)和 bind 函數(shù)的優(yōu)先級(jí)更高了,有興趣可自行嘗試吧。

6. 直接調(diào)用

在函數(shù)不滿足前面的場(chǎng)景,被直接調(diào)用時(shí),this 將指向全局對(duì)象。在瀏覽器環(huán)境中全局對(duì)象是 Window,在 Node.js 環(huán)境中是 Global。

先來個(gè)簡(jiǎn)單的例子。

?
1
2
3
4
5
function func() {
  console.log(this)
}
 
func() // Window

來一個(gè)復(fù)雜的例子,外層的 outerFunc 就起個(gè)迷惑目的。

?
1
2
3
4
5
6
7
8
9
10
11
function outerFunc() {
  console.log(this) // { x: 1 }
 
  function func() {
    console.log(this) // Window
  }
 
  func()
}
 
outerFunc.bind({ x: 1 })()

7. 不在函數(shù)里

不在函數(shù)中的場(chǎng)景,可分為瀏覽器的 <script /> 標(biāo)簽里,或 Node.js 的模塊文件里。

  1. 在 <script /> 標(biāo)簽里,this 指向 Window。
  2. 在 Node.js 的模塊文件里,this 指向 Module 的默認(rèn)導(dǎo)出對(duì)象,也就是 module.exports。

非嚴(yán)格模式

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

例如下面的代碼,在非嚴(yán)格模式下,this 都指向全局對(duì)象。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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()

非嚴(yán)格模式下執(zhí)行結(jié)果為:

JavaScript中的this指向問題詳解

在嚴(yán)格模式下,執(zhí)行同樣的代碼進(jìn)行對(duì)比。記住要一次性將所有代碼復(fù)制粘貼到控制臺(tái)中,才能運(yùn)行在嚴(yán)格模式下(因?yàn)榈谝恍?"use strict" 才會(huì)對(duì)后面的代碼生效)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"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()

嚴(yán)格模式下執(zhí)行結(jié)果為:

JavaScript中的this指向問題詳解

七步口訣在嚴(yán)格模式下和非嚴(yán)格模式下都是完備的,只是在非嚴(yán)格模式下 null 或 undefined 會(huì)被轉(zhuǎn)換為全局對(duì)象。所以我沒有將這點(diǎn)列入口訣中。

做題復(fù)習(xí)

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

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

?
1
2
3
4
5
6
function func(num) {
  this.count++
}
 
func.count = 0
func(1)

答案

func.count 值為 0。

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

2. 以下箭頭函數(shù)中 this 指向誰(shuí)呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

是不是很簡(jiǎn)單,你學(xué)廢了嗎?

總結(jié)

到此這篇關(guān)于JavaScript中的this指向問題的文章就介紹到這了,更多相關(guān)js中this指向內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6946021671656488991

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品亚洲精品国产欧美 | 色综合伊人色综合网亚洲欧洲 | 日本videosdesexo乱 | 亚洲欧美日韩精品高清 | 丰满的闺蜜2中文字幕 | 特黄视频免费看 | 欧美 变态 另类 人妖班 | 午夜成私人影院在线观看 | 免费看视频高清在线观看 | 免费观看成年肉动漫网站 | 色屁屁二区 | 精品国产一区二区三区久久久狼 | 精品夜夜澡人妻无码AV蜜桃 | 亚洲a在线视频 | japanese在线观看 | 99热国产这里只有精品 | 亚洲精品综合一区二区 | 亚洲国产日韩欧美一区二区三区 | 国产精品视频久久 | 国产精品免费久久久久影院小说 | 精品在线小视频 | 日本国产一区二区三区 | bestialitysex杂交 bedfriend泰剧全集免费观看 | 精品福利一区二区免费视频 | 成人精品亚洲人成在线 | 色香婷婷 | 亚洲经典| 国产精品美女福利视频免费专区 | 娇小性色 | 99re热| 欧洲网色偷偷亚洲男人的天堂 | 美女校花被调教出奶水 | 99这里只有精品66视频 | 亚洲精品永久免费 | 成人中文字幕在线高清 | 午夜无码国产理论在线 | 日本中文字幕永久在线 | 成人欧美一区二区三区白人 | 92国产福利久久青青草原 | 疯狂激吻添下边小说 | 久久不卡免费视频 |