亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
1. 關(guān)於 this 的簡(jiǎn)單介紹
2. 為什麼要用 this?
3. 關(guān)於this 的常見(jiàn)的誤解
4. this 的綁定規(guī)則
4.1 預(yù)設(shè)綁定
4.2 隱式綁定
4.2.1 一般的對(duì)象調(diào)用
4.2.2 對(duì)象屬性引用鏈
4.2.3 隱式丟失
4.3 顯式綁定
4.3.1 使用 call(...) 和 apply(...)
4.3.2 硬綁定(一個(gè)函數(shù)總是顯示的綁定到一個(gè)對(duì)象上)
4.3.3 API調(diào)用的 “上下文(內(nèi)置函數(shù))
4.4 new 綁定
5. 綁定規(guī)則的優(yōu)先級(jí)
5.1 默認(rèn)綁定的優(yōu)先級(jí)最低
5.2 隱式綁定和顯式綁定的優(yōu)先級(jí)比較
5.3 隱式綁定和 new 綁定的優(yōu)先級(jí)比較
5.4 new 綁定和顯示綁定的優(yōu)先級(jí)比較
6. 判斷this
7. 綁定例外
7.1 箭頭函數(shù)
7.2 被忽略的this
7.3 間接引用
8. this 判斷例題
8.1 例題一
8.2 例題二
9. 總結(jié)
首頁(yè) web前端 js教程 帶你去詳解 this 的四個(gè)綁定規(guī)則

帶你去詳解 this 的四個(gè)綁定規(guī)則

Nov 01, 2022 pm 05:49 PM
javascript this

帶你去詳解 this 的四個(gè)綁定規(guī)則

1. 關(guān)於 this 的簡(jiǎn)單介紹

this 關(guān)鍵字是 JavaScript 中最複雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在所有函數(shù)的作用域中。但即使是非常有經(jīng)驗(yàn)的 JavaScript 開(kāi)發(fā)者也很難說(shuō)清它到底指向什麼。

任何足夠先進(jìn)的技術(shù)都和魔法無(wú)異。 — Arthur C. Clarke

實(shí)際上,JavaScript 中this 的機(jī)制並沒(méi)有那麼先進(jìn),但是開(kāi)發(fā)者往往會(huì)把理解過(guò)程複雜化, 毫無(wú)疑問(wèn),在缺乏清晰認(rèn)識(shí)的情況下, this 對(duì)你來(lái)說(shuō)完全就是一種魔法。

2. 為什麼要用 this?

const obj = {
  title: '掘金',
  reading() {
    console.log(this.title + ',一個(gè)幫助開(kāi)發(fā)者成長(zhǎng)的社區(qū)');
  }
}

this 提供了一種更優(yōu)雅的方式來(lái)隱式「?jìng)鬟f」一個(gè)物件引用,因此可以將 API 設(shè)計(jì)得更加簡(jiǎn)潔並且易於復(fù)用。

隨著你的使用模式越來(lái)越複雜,明確傳遞上下文物件會(huì)讓程式碼變得越來(lái)越混亂,使用 this 則不會(huì)這樣。當(dāng)我們介紹物件和原型時(shí),你就會(huì)明白函數(shù)可以自動(dòng)引用合適的上下文物件有多重要

3. 關(guān)於this 的常見(jiàn)的誤解

人們很容易把this 理解成指向函數(shù)本身,JavaScript 的新手開(kāi)發(fā)者通常會(huì)認(rèn)為,既然把函數(shù)看作一個(gè)物件(JavaScript 中的所有函數(shù)都是物件),那就可以在呼叫函數(shù)時(shí)儲(chǔ)存狀態(tài)(屬性的值)。但結(jié)果通常會(huì)讓他們大吃一驚,例如下面這段程式碼

function foo() {
  // 讓新添加的 count + 1
  this.count++
}

// 向函數(shù)對(duì)象 foo 添加了一個(gè)屬性 count
foo.count = 0

foo()

console.log(foo.count);   // 0

這段程式碼看起來(lái)沒(méi)什麼問(wèn)題,但請(qǐng)把目光聚焦到最後一行,輸出foo.count 的結(jié)果竟然是0 ? !

疑問(wèn):為什麼會(huì)這樣?我明明向函數(shù)物件foo 新增了一個(gè)屬性count,並且函數(shù)內(nèi)部也寫了this.count ,為什麼最後還是0呢?

解答:因?yàn)?code>this.count 中此時(shí)的this,根本不是指向foo 函數(shù)自身,而是指向全域window。再細(xì)心一點(diǎn),我們可以發(fā)現(xiàn),在 window 身上,被加入了個(gè) count 屬性,值為 NaN。 (為什麼 this 指向 window 後面會(huì)闡述)

帶你去詳解 this 的四個(gè)綁定規(guī)則所以,單純的把 this 理解為指向函數(shù)本身是錯(cuò)誤的。

this 實(shí)際上是在函數(shù)被呼叫時(shí)發(fā)生的綁定,它指向什麼完全取決於函數(shù)在哪裡被呼叫。

4. this 的綁定規(guī)則

我們來(lái)看看在函數(shù)的執(zhí)行過(guò)程中呼叫位置如何決定 this 的綁定物件。

找到呼叫位置,然後判斷需要套用下面四條規(guī)則中的哪一條。我首先會(huì)分別解釋 這四條規(guī)則,然後解釋多條規(guī)則都可用時(shí)它們的優(yōu)先順序如何排列。

4.1 預(yù)設(shè)綁定

首先要介紹的是最常用的函數(shù)呼叫類型:獨(dú)立函數(shù)呼叫??梢园堰@條規(guī)則看成是無(wú)法套用其他規(guī)則時(shí)的預(yù)設(shè)規(guī)則。

function foo() {
  console.log(this.a)
}
var a = 2
foo() // 2
  • 我們可以看到當(dāng)呼叫foo() 時(shí),this.a 被解析變成全域變數(shù)a 。為什麼?因?yàn)樵诒纠校?strong>函數(shù)呼叫時(shí)應(yīng)用了 this 的預(yù)設(shè)綁定,因此 this 指向全域物件。

  • 那我們?cè)觞N知道這裡應(yīng)用了預(yù)設(shè)綁定呢?可以透過(guò)分析呼叫位置來(lái)看看 foo() 是如何調(diào) 用的。在程式碼中,foo() 是直接使用不帶任何修飾的函數(shù)參考進(jìn)行呼叫的,因此只能使用預(yù)設(shè)綁定,無(wú)法應(yīng)用其他規(guī)則

  • #這條規(guī)則也解釋了上面count 的程式碼中,為什麼函數(shù)裡面的this指向了window,因?yàn)?code>foo 是屬於獨(dú)立函數(shù)呼叫的,觸發(fā)了預(yù)設(shè)綁定,從而指向全域window。 (瀏覽器中全域是window對(duì)象,node 中是空對(duì)象{})

  • #屬於預(yù)設(shè)綁定規(guī)則的還有:

    • 函數(shù)呼叫鏈(一個(gè)函數(shù)又呼叫另外一個(gè)函數(shù))
    • 將函數(shù)當(dāng)作參數(shù),傳入到另一個(gè)函數(shù)

(擴(kuò)充:如果使用嚴(yán)格模式( strict mode),則不能將全域物件用於預(yù)設(shè)綁定,因此this 會(huì)綁定到undefined:)

結(jié)論:預(yù)設(shè)綁定的this,都指向全域。

4.2 隱式綁定

4.2.1 一般的對(duì)象調(diào)用

這一條需要考慮的規(guī)則是調(diào)用位置是否有上下文對(duì)象,或者說(shuō)是通過(guò)某個(gè)對(duì)象發(fā)起的函數(shù)調(diào)用

function foo() {
  console.log(this.a)
}

const obj = {
  a: 2,
  foo: foo
}

// 通過(guò) obj 對(duì)象調(diào)用 foo 函數(shù)
obj.foo() // 2
  • 調(diào)用位置會(huì)使用 obj 上下文來(lái)引用函數(shù),因此你可以說(shuō)函數(shù)被調(diào)用時(shí) obj 對(duì)象“擁 有”或者“包含”它。

  • foo() 被調(diào)用時(shí),它的前面確實(shí)加上了對(duì) obj 的引用。當(dāng)函數(shù)引用有上下文對(duì)象時(shí),隱式綁定規(guī)則會(huì)把函數(shù)調(diào)用中的 this 綁定到這個(gè)上下文對(duì)象。因?yàn)檎{(diào)用 foo() 時(shí) this 被綁定到 obj 上,因此 this.aobj.a 是一樣的。

4.2.2 對(duì)象屬性引用鏈

對(duì)象屬性引用鏈中只有上一層或者說(shuō)最后一層在調(diào)用位置中起作用。舉例來(lái)說(shuō):

function foo() {
  console.log(this.a)
}

var obj2 = {
  a: 2,
  foo: foo
}

var obj1 = {
  a: 1,
  obj2: obj2
}

obj1.obj2.foo() // 2

最終 this 指向的是 obj2

4.2.3 隱式丟失

一個(gè)最常見(jiàn)的 this 綁定問(wèn)題就是被隱式綁定的函數(shù)會(huì)丟失綁定對(duì)象,也就是說(shuō)它會(huì)應(yīng)用默認(rèn)綁定,從而把 this 綁定到全局對(duì)象或者 undefined 上(取決于是否是嚴(yán)格模式)

第一種情況:將對(duì)象里的函數(shù)賦值給一個(gè)變量

function foo() {
  console.log(this.a)
}

var obj = {
  a: 2,
  foo: foo
}

var bar = obj.foo // 函數(shù)別名!

var a = 'global' // a 是全局對(duì)象的屬性
bar() // "global"

雖然 barobj.foo 的一個(gè)引用,但是實(shí)際上,它引用的是 foo 函數(shù)本身,因此此時(shí)的 bar() 其實(shí)是一個(gè)不帶任何修飾的函數(shù)調(diào)用,因此應(yīng)用了默認(rèn)綁定。

第二種情況:傳入回調(diào)函數(shù)時(shí)

function foo() {
  console.log(this.a)
}

function doFoo(fn) {
  // fn 其實(shí)引用的是 foo
  fn() // <-- 調(diào)用位置!
}

var obj = {
  a: 2,
  foo: foo
}

var a = &#39;global&#39;  // a 是全局對(duì)象的屬性
doFoo(obj.foo)    // "global"

參數(shù)傳遞其實(shí)就是一種隱式賦值,因此我們傳入函數(shù)時(shí)也會(huì)被隱式賦值,所以結(jié)果和上一 個(gè)例子一樣。

結(jié)論:隱式綁定的 this,指向調(diào)用函數(shù)的上下文對(duì)象。

4.3 顯式綁定

4.3.1 使用 call(...) 和 apply(...)

如果我們不想在對(duì)象內(nèi)部包含函數(shù)引用,而想在某個(gè)對(duì)象上強(qiáng)制調(diào)用函數(shù),該怎么做呢?可以使用函數(shù)的 call(..)apply(..) 方法

  • JavaScript 提供的絕大多數(shù)函數(shù)以及你自 己創(chuàng)建的所有函數(shù)都可以使用 call(..)apply(..) 方法。

這兩個(gè)方法是如何工作的呢?它們的第一個(gè)參數(shù)是一個(gè)對(duì)象,是給 this 準(zhǔn)備的,接著在調(diào)用函數(shù)時(shí)將其綁定到 this。因?yàn)槟憧梢灾苯又付?this 的綁定對(duì)象,因此我們稱之為顯式綁定。 思考以下代碼:

function foo() {
  console.log(this.a)
}

var obj = {
  a: 2
}

foo.call(obj) // 2
  • 通過(guò) foo.call(..),我們可以在調(diào)用 foo 時(shí)強(qiáng)制把它的 this 綁定到 obj 上。

  • 如果你傳入了一個(gè)原始值(字符串類型、布爾類型或者數(shù)字類型)來(lái)當(dāng)作 this 的綁定對(duì) 象,這個(gè)原始值會(huì)被轉(zhuǎn)換成它的對(duì)象形式(也就是 new String(..)、new Boolean(..) 或者 new Number(..))。這通常被稱為“裝箱”。

從 this 綁定的角度來(lái)說(shuō),call(..) 和 apply(..) 是一樣的,它們的區(qū)別體現(xiàn)在參數(shù)上:第一個(gè)參數(shù)是相同的,后面的參數(shù),call為參數(shù)列表,apply為數(shù)組,他們內(nèi)部的實(shí)現(xiàn)原理也不難理解,詳細(xì)請(qǐng)看以下兩個(gè)手寫方法

4.3.2 硬綁定(一個(gè)函數(shù)總是顯示的綁定到一個(gè)對(duì)象上)

由于硬綁定是一種非常常用的模式,所以 ES5 提供了內(nèi)置的方法 Function.prototype.bind, 它的用法如下

function foo(num) {
  console.log(this.a, num)
  return this.a + num
}

var obj = {
  a: 2
}

// 調(diào)用 bind() 方法,返回一個(gè)函數(shù)
var bar = foo.bind(obj)

var b = bar(3) // 2 3

console.log(b) // 5

調(diào)用 bind(...) 方法,會(huì)返回一個(gè)新函數(shù),那么這個(gè)新函數(shù)的 this,永遠(yuǎn)指向我們傳入的obj對(duì)象

關(guān)于 bind 方法的簡(jiǎn)單實(shí)現(xiàn),可以前往:手寫 bind 方法,超級(jí)詳細(xì) ???

4.3.3 API調(diào)用的 “上下文(內(nèi)置函數(shù))

第三方庫(kù)的許多函數(shù),以及 JavaScript 語(yǔ)言和宿主環(huán)境中許多新的內(nèi)置函數(shù),都提供了一個(gè)可選的參數(shù),通常被稱為“上下文”(context),其作用和 bind(..) 一樣,確保你的回調(diào)函數(shù)使用指定的 this。例如:

(1)數(shù)組方法 forEach()

function foo(el) {
  console.log(el, this.id)
}

var obj = {
  id: &#39;bin&#39;
};

[1, 2, 3].forEach(foo, obj)

// 輸出:
// 1 bin 
// 2 bin 
// 3 bin
  • 調(diào)用 foo(..) 時(shí)把 this 綁定到 obj 身上

(2)setTimeout()

setTimeout(function() {
  console.log(this); // window
}, 1000);
  • 在使用 setTimeout 時(shí)會(huì)傳入一個(gè)回調(diào)函數(shù),而這個(gè)回調(diào)函數(shù)中的this一般指向 window,這個(gè)和 setTimeout 源碼的內(nèi)部調(diào)用有關(guān),這個(gè)不再展開(kāi)贅述

結(jié)論:顯式綁定的 this,指向我們指定的綁定對(duì)象。

4.4 new 綁定

在 JavaScript 中,普通函數(shù)可以使用 new 操作符去調(diào)用,此時(shí)的普通函數(shù)則被稱為 “構(gòu)造函數(shù)”。沒(méi)錯(cuò),凡是由 new 操作符調(diào)用的函數(shù),都稱為 “構(gòu)造函數(shù)”

使用 new 來(lái)調(diào)用函數(shù),或者說(shuō)發(fā)生構(gòu)造函數(shù)調(diào)用時(shí),會(huì)自動(dòng)執(zhí)行下面的操作。

  • 在內(nèi)存中創(chuàng)建一個(gè)新對(duì)象。

  • 這個(gè)新對(duì)象內(nèi)部的[[Prototype]] 特性被賦值為構(gòu)造函數(shù)的 prototype 屬性。

  • 構(gòu)造函數(shù)內(nèi)部的this 被賦值為這個(gè)新對(duì)象(即this 指向新對(duì)象)。

  • 執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼(給新對(duì)象添加屬性)。

  • 如果構(gòu)造函數(shù)返回非空對(duì)象,則返回該對(duì)象;否則,返回剛創(chuàng)建的新對(duì)象。

function foo(a) {
  this.a = a
}

var bar = new foo(2)

console.log(bar.a) // 2

使用 new 來(lái)調(diào)用 foo(..) 時(shí),我們會(huì)構(gòu)造一個(gè)新對(duì)象并把它綁定到 foo(..) 調(diào)用中的 this 上。new 是最后一種可以影響函數(shù)調(diào)用時(shí) this 綁定行為的方法,我們稱之為 new 綁定。

結(jié)論:new 綁定的 this,都指向通過(guò) new 調(diào)用的函數(shù)的實(shí)例對(duì)象(就是該函數(shù))

5. 綁定規(guī)則的優(yōu)先級(jí)

現(xiàn)在我們已經(jīng)了解了函數(shù)調(diào)用中 this 綁定的四條規(guī)則,你需要做的就是找到函數(shù)的調(diào)用位置并判斷應(yīng)當(dāng)應(yīng)用哪條規(guī)則。但是,如果某個(gè)調(diào)用位置可以應(yīng)用多條規(guī)則呢?所以就需要有綁定規(guī)則的優(yōu)先級(jí)。

它們之間的優(yōu)先級(jí)關(guān)系為:

默認(rèn)綁定 < 隱式綁定 < 顯示綁定(bind) < new綁定

這里提前列出優(yōu)先級(jí),想看詳細(xì)代碼解析的可以往下看,也可以直接拖到最后面的例題部分

5.1 默認(rèn)綁定的優(yōu)先級(jí)最低

毫無(wú)疑問(wèn),默認(rèn)規(guī)則的優(yōu)先級(jí)是最低的,因?yàn)榇嬖谄渌?guī)則時(shí),就會(huì)通過(guò)其他規(guī)則的方式來(lái)綁定this

5.2 隱式綁定和顯式綁定的優(yōu)先級(jí)比較

測(cè)試一下即可知道,有以下代碼:

function foo() {
  console.log(this.a)
}

var obj1 = {
  a: 1,
  foo: foo
}

var obj2 = {
  a: 2,
  foo: foo
}

// 同時(shí)使用隱式綁定和顯示綁定
obj1.foo.call(obj2) // 2

可以看到,輸出的結(jié)果為 2,說(shuō)明 foo 函數(shù)內(nèi) this 指向的是 obj2,而 obj2 是通過(guò)顯示綁定調(diào)用的,所以:顯示綁定的優(yōu)先級(jí)更高

5.3 隱式綁定和 new 綁定的優(yōu)先級(jí)比較

有以下測(cè)試代碼:

function foo() {
  console.log(this);
}

var obj = {
  title: "juejin",
  foo: foo
}

// 同時(shí)使用隱式綁定和new綁定
new obj.foo(); // foo對(duì)象

最后 foo 函數(shù)輸出的 this 為 foo 對(duì)象,說(shuō)明new綁定優(yōu)先級(jí)更高(否則應(yīng)該輸出 obj 對(duì)象),所以:new 綁定的優(yōu)先級(jí)更高

5.4 new 綁定和顯示綁定的優(yōu)先級(jí)比較

最后,new 綁定和顯式綁定誰(shuí)的優(yōu)先級(jí)更高呢?

new綁定和call、apply是不允許同時(shí)使用的,只能和 bind 相比較,如下:

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

var obj = {
  title: "juejin"
}

var foo = new foo.call(obj);  // 直接報(bào)錯(cuò)

但是 new 綁定可以和 bind 方法返回后的函數(shù)一起使用

function foo() {
  console.log(this);
}

var obj = {
  title: "juejin"
}

var bar = foo.bind(obj);

var foo = new bar(); // foo 對(duì)象, 說(shuō)明使用的是new綁定

最后 foo 函數(shù)輸出的 this 為 foo 對(duì)象,說(shuō)明new綁定優(yōu)先級(jí)更高(否則應(yīng)該輸出 obj 對(duì)象),所以:new 綁定的優(yōu)先級(jí)更高

優(yōu)先級(jí)結(jié)論:默認(rèn)綁定 < 隱式綁定 < 顯示綁定(bind)< new綁定

6. 判斷this

現(xiàn)在我們可以根據(jù)優(yōu)先級(jí)來(lái)判斷函數(shù)在某個(gè)調(diào)用位置應(yīng)用的是哪條規(guī)則??梢园凑障旅娴?順序來(lái)進(jìn)行判斷:

  • 函數(shù)是否在 new 中調(diào)用(new 綁定)?如果是的話 this 綁定的是新創(chuàng)建的對(duì)象。 var bar = new foo()

  • 函數(shù)是否通過(guò) call、apply(顯式綁定)或者硬綁定調(diào)用?如果是的話,this 綁定的是 指定的對(duì)象。 var bar = foo.call(obj2)

  • 函數(shù)是否在某個(gè)上下文對(duì)象中調(diào)用(隱式綁定)?如果是的話,this 綁定的是那個(gè)上 下文對(duì)象。 var bar = obj1.foo()

  • 如果都不是的話,使用默認(rèn)綁定。如果在嚴(yán)格模式下,就綁定到 undefined,否則綁定 到全局對(duì)象。 var bar = foo()

就是這樣。對(duì)于正常的函數(shù)調(diào)用來(lái)說(shuō),理解了這些知識(shí)你就可以明白 this 的綁定原理了。 不過(guò)……凡事總有例外

7. 綁定例外

規(guī)則總有例外,這里也一樣。在某些場(chǎng)景下 this 的綁定行為會(huì)出乎意料,你認(rèn)為應(yīng)當(dāng)應(yīng)用其他綁定規(guī)則時(shí),實(shí)際上應(yīng)用的可能是默認(rèn)綁定規(guī)則。

7.1 箭頭函數(shù)

箭頭函數(shù)不使用 this 的四種標(biāo)準(zhǔn)規(guī)則,而是根據(jù)外層(函數(shù)或者全局)作用域來(lái)決定 this。

7.2 被忽略的this

如果你把 null 或者 undefined 作為 this 的綁定對(duì)象傳入 call、apply 或者 bind,這些值在調(diào)用時(shí)會(huì)被忽略,實(shí)際應(yīng)用的是默認(rèn)綁定規(guī)則:

function foo() {
  console.log(this.a)
}

var a = 2

foo.call(null) // 2
foo.call(undefined) // 2
foo.bind(null)();

最后輸出的結(jié)果都是 2,說(shuō)明 this 指向的是全局 window

7.3 間接引用

另一個(gè)需要注意的是,你有可能(有意或者無(wú)意地)創(chuàng)建一個(gè)函數(shù)的間接引用,在這種情況下,調(diào)用這個(gè)函數(shù)會(huì)應(yīng)用默認(rèn)綁定規(guī)則。 間接引用最容易在賦值時(shí)發(fā)生:

function foo() {
  console.log(this.a)
}
var a = 2
var o = { a: 3, foo: foo }
var p = { a: 4 }

o.foo(); // 3

// 函數(shù)賦值
(p.foo = o.foo)()  // 2

賦值表達(dá)式 p.foo = o.foo 的返回值是目標(biāo)函數(shù)的引用,因此調(diào)用位置是 foo() 屬于獨(dú)立函數(shù)調(diào)用,而不是 p.foo() 或者 o.foo()。根據(jù)我們之前說(shuō)過(guò)的,這里會(huì)應(yīng)用默認(rèn)綁定。

8. this 判斷例題

請(qǐng)說(shuō)出例題中的輸出結(jié)果

8.1 例題一

var name = "window";
var person = {
  name: "person",
  sayName: function () {
    console.log(this.name);
  }
};
function sayName() {
  var sss = person.sayName;
  sss(); 
  person.sayName(); 
  (person.sayName)(); 
  (b = person.sayName)(); 
}
sayName();

解析:

function sayName() {
  var sss = person.sayName;
  // 獨(dú)立函數(shù)調(diào)用,沒(méi)有和任何對(duì)象關(guān)聯(lián)
  sss(); // window
  // 關(guān)聯(lián)
  person.sayName(); // person
  (person.sayName)(); // person
  (b = person.sayName)(); // window
}

8.2 例題二

var name = &#39;window&#39;
var person1 = {
  name: &#39;person1&#39;,
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}

var person2 = { name: &#39;person2&#39; }

person1.foo1(); 
person1.foo1.call(person2); 

person1.foo2();
person1.foo2.call(person2);

person1.foo3()();
person1.foo3.call(person2)();
person1.foo3().call(person2);

person1.foo4()();
person1.foo4.call(person2)();
person1.foo4().call(person2);

解析:

// 隱式綁定,肯定是person1
person1.foo1(); // person1
// 隱式綁定和顯示綁定的結(jié)合,顯示綁定生效,所以是person2
person1.foo1.call(person2); // person2

// foo2()是一個(gè)箭頭函數(shù),不適用所有的規(guī)則
person1.foo2() // window
// foo2依然是箭頭函數(shù),不適用于顯示綁定的規(guī)則
person1.foo2.call(person2) // window

// 獲取到foo3,但是調(diào)用位置是全局作用于下,所以是默認(rèn)綁定window
person1.foo3()() // window
// foo3顯示綁定到person2中
// 但是拿到的返回函數(shù)依然是在全局下調(diào)用,所以依然是window
person1.foo3.call(person2)() // window
// 拿到foo3返回的函數(shù),通過(guò)顯示綁定到person2中,所以是person2
person1.foo3().call(person2) // person2

// foo4()的函數(shù)返回的是一個(gè)箭頭函數(shù)
// 箭頭函數(shù)的執(zhí)行找上層作用域,是person1
person1.foo4()() // person1
// foo4()顯示綁定到person2中,并且返回一個(gè)箭頭函數(shù)
// 箭頭函數(shù)找上層作用域,是person2
person1.foo4.call(person2)() // person2
// foo4返回的是箭頭函數(shù),箭頭函數(shù)只看上層作用域
person1.foo4().call(person2) // person1

9. 總結(jié)

如果要判斷一個(gè)運(yùn)行中函數(shù)的 this 綁定,就需要找到這個(gè)函數(shù)的直接調(diào)用位置。找到之后就可以順序應(yīng)用下面這四條規(guī)則來(lái)判斷 this 的綁定對(duì)象。

  • 由 new 調(diào)用?綁定到新創(chuàng)建的對(duì)象。

  • 由 call 或者 apply(或者 bind)調(diào)用?綁定到指定的對(duì)象。

  • 由上下文對(duì)象調(diào)用?綁定到那個(gè)上下文對(duì)象。

  • 默認(rèn):在嚴(yán)格模式下綁定到 undefined,否則綁定到全局對(duì)象。


每文一句:如果把生活比喻為創(chuàng)作的意境,那么閱讀就像陽(yáng)光。

ok,本次的分享就到這里,如果本章內(nèi)容對(duì)你有所幫助的話可以點(diǎn)贊+收藏,希望大家都能夠有所收獲。有任何疑問(wèn)都可以在評(píng)論區(qū)留言,大家一起探討、進(jìn)步!

【推薦學(xué)習(xí):javascript高級(jí)教程

以上是帶你去詳解 this 的四個(gè)綁定規(guī)則的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
WebSocket與JavaScript:實(shí)現(xiàn)即時(shí)監(jiān)控系統(tǒng)的關(guān)鍵技術(shù) WebSocket與JavaScript:實(shí)現(xiàn)即時(shí)監(jiān)控系統(tǒng)的關(guān)鍵技術(shù) Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實(shí)現(xiàn)即時(shí)監(jiān)控系統(tǒng)的關(guān)鍵技術(shù)引言:隨著互聯(lián)網(wǎng)技術(shù)的快速發(fā)展,即時(shí)監(jiān)控系統(tǒng)在各個(gè)領(lǐng)域中得到了廣泛的應(yīng)用。而實(shí)現(xiàn)即時(shí)監(jiān)控的關(guān)鍵技術(shù)之一就是WebSocket與JavaScript的結(jié)合使用。本文將介紹WebSocket與JavaScript在即時(shí)監(jiān)控系統(tǒng)中的應(yīng)用,並給出程式碼範(fàn)例,詳細(xì)解釋其實(shí)作原理。一、WebSocket技

如何使用WebSocket和JavaScript實(shí)現(xiàn)線上語(yǔ)音辨識(shí)系統(tǒng) 如何使用WebSocket和JavaScript實(shí)現(xiàn)線上語(yǔ)音辨識(shí)系統(tǒng) Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實(shí)現(xiàn)線上語(yǔ)音辨識(shí)系統(tǒng)引言:隨著科技的不斷發(fā)展,語(yǔ)音辨識(shí)技術(shù)已成為了人工智慧領(lǐng)域的重要組成部分。而基於WebSocket和JavaScript實(shí)現(xiàn)的線上語(yǔ)音辨識(shí)系統(tǒng),具備了低延遲、即時(shí)性和跨平臺(tái)的特點(diǎn),成為了廣泛應(yīng)用的解決方案。本文將介紹如何使用WebSocket和JavaScript來(lái)實(shí)現(xiàn)線上語(yǔ)音辨識(shí)系

如何利用JavaScript和WebSocket實(shí)現(xiàn)即時(shí)線上點(diǎn)餐系統(tǒng) 如何利用JavaScript和WebSocket實(shí)現(xiàn)即時(shí)線上點(diǎn)餐系統(tǒng) Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實(shí)現(xiàn)即時(shí)線上點(diǎn)餐系統(tǒng)介紹:隨著網(wǎng)路的普及和技術(shù)的進(jìn)步,越來(lái)越多的餐廳開(kāi)始提供線上點(diǎn)餐服務(wù)。為了實(shí)現(xiàn)即時(shí)線上點(diǎn)餐系統(tǒng),我們可以利用JavaScript和WebSocket技術(shù)。 WebSocket是一種基於TCP協(xié)定的全雙工通訊協(xié)議,可實(shí)現(xiàn)客戶端與伺服器的即時(shí)雙向通訊。在即時(shí)線上點(diǎn)餐系統(tǒng)中,當(dāng)使用者選擇菜餚並下訂單

JavaScript與WebSocket:打造高效率的即時(shí)天氣預(yù)報(bào)系統(tǒng) JavaScript與WebSocket:打造高效率的即時(shí)天氣預(yù)報(bào)系統(tǒng) Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時(shí)天氣預(yù)報(bào)系統(tǒng)引言:如今,天氣預(yù)報(bào)的準(zhǔn)確性對(duì)於日常生活以及決策制定具有重要意義。隨著技術(shù)的發(fā)展,我們可以透過(guò)即時(shí)獲取天氣數(shù)據(jù)來(lái)提供更準(zhǔn)確可靠的天氣預(yù)報(bào)。在本文中,我們將學(xué)習(xí)如何使用JavaScript和WebSocket技術(shù),來(lái)建立一個(gè)高效的即時(shí)天氣預(yù)報(bào)系統(tǒng)。本文將透過(guò)具體的程式碼範(fàn)例來(lái)展示實(shí)現(xiàn)的過(guò)程。 We

如何使用WebSocket和JavaScript實(shí)現(xiàn)線上預(yù)約系統(tǒng) 如何使用WebSocket和JavaScript實(shí)現(xiàn)線上預(yù)約系統(tǒng) Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實(shí)現(xiàn)線上預(yù)約系統(tǒng)在當(dāng)今數(shù)位化的時(shí)代,越來(lái)越多的業(yè)務(wù)和服務(wù)都需要提供線上預(yù)約功能。而實(shí)現(xiàn)一個(gè)高效、即時(shí)的線上預(yù)約系統(tǒng)是至關(guān)重要的。本文將介紹如何使用WebSocket和JavaScript來(lái)實(shí)作一個(gè)線上預(yù)約系統(tǒng),並提供具體的程式碼範(fàn)例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進(jìn)行全雙工

簡(jiǎn)易JavaScript教學(xué):取得HTTP狀態(tài)碼的方法 簡(jiǎn)易JavaScript教學(xué):取得HTTP狀態(tài)碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學(xué):如何取得HTTP狀態(tài)碼,需要具體程式碼範(fàn)例前言:在Web開(kāi)發(fā)中,經(jīng)常會(huì)涉及到與伺服器進(jìn)行資料互動(dòng)的場(chǎng)景。在與伺服器進(jìn)行通訊時(shí),我們經(jīng)常需要取得傳回的HTTP狀態(tài)碼來(lái)判斷操作是否成功,並根據(jù)不同的狀態(tài)碼來(lái)進(jìn)行對(duì)應(yīng)的處理。本篇文章將教你如何使用JavaScript來(lái)取得HTTP狀態(tài)碼,並提供一些實(shí)用的程式碼範(fàn)例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹(shù)中插入一個(gè)新的節(jié)點(diǎn)。這個(gè)方法需要兩個(gè)參數(shù):要插入的新節(jié)點(diǎn)和參考節(jié)點(diǎn)(即新節(jié)點(diǎn)將要插入的位置的節(jié)點(diǎn))。

如何在JavaScript中取得HTTP狀態(tài)碼的簡(jiǎn)單方法 如何在JavaScript中取得HTTP狀態(tài)碼的簡(jiǎn)單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態(tài)碼取得方法簡(jiǎn)介:在進(jìn)行前端開(kāi)發(fā)中,我們常常需要處理與後端介面的交互,而HTTP狀態(tài)碼就是其中非常重要的一部分。了解並取得HTTP狀態(tài)碼有助於我們更好地處理介面?zhèn)骰氐馁Y料。本文將介紹使用JavaScript取得HTTP狀態(tài)碼的方法,並提供具體程式碼範(fàn)例。一、什麼是HTTP狀態(tài)碼HTTP狀態(tài)碼是指當(dāng)瀏覽器向伺服器發(fā)起請(qǐng)求時(shí),服務(wù)

See all articles