關(guān)于this

1 this初步

?????this 實(shí)際上是在函數(shù)被調(diào)用時(shí)發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用。

1.1 對(duì) this 的誤解

  • 容易把 this 理解成指向函數(shù)自身
<script type="text/javascript">
function foo(num) {
    console.log("foo: " + num );
    this.count++;
} 
foo.count = 0;
var i; 
for (i=0; i<10; i++) {
    if (i > 5){foo( i );}
} 
console.log(foo.count);
//0
</script>

? ? ? ?在上面,foo是一個(gè)函數(shù)對(duì)象,foo.count為foo添加了一個(gè)count屬性,其實(shí)是window.foo.count=0。
? ? ? ?條件語(yǔ)句、循環(huán)迭代語(yǔ)句、console.log并不會(huì)改變上下文this。因此,在for語(yǔ)句中,this指向window,調(diào)用的是window.foo(i),foo中增加的是count是window.count,而不是window.foo.count,foo.count依然為0.
? ? ? ?解決辦法是強(qiáng)制 this 指向 foo 函數(shù)對(duì)象:

<script type="text/javascript">
function foo(num) {
    console.log("foo: " + num );
    this.count++;
} 
foo.count = 0;
var i; 
for (i=0; i<10; i++) {
    if (i > 5){
        foo.call(foo, i ); // 把this指向foo
    }
} 
console.log(foo.count);
//4
</script>
  • 第2種常見(jiàn)的誤解是,this 指向函數(shù)的作用域
    ? ? ? ?這個(gè)問(wèn)題有點(diǎn)復(fù)雜,因?yàn)樵谀撤N情況下它是正確的,但有時(shí)卻是錯(cuò)誤的
    ? ? ? ?首先,這段代碼試圖通過(guò) this.bar() 來(lái)引用 bar() 函數(shù)。這是絕對(duì)不可能成功的,我們之后會(huì)解釋原因。調(diào)用 bar() 最自然的方法是省略前面的 this,直接使用詞法引用標(biāo)識(shí)符。
    ? ? ? ?此外,編寫(xiě)這段代碼的開(kāi)發(fā)者還試圖使用 this 聯(lián)通 foo() 和 bar() 的詞法作用域,從而讓 bar() 可以訪問(wèn) foo() 作用域里的變量 a。這是不可能實(shí)現(xiàn)的,你不能使用 this 來(lái)引用一 個(gè)詞法作用域內(nèi)部的東西。
    ? ? ? ?每當(dāng)你想要把 this 和詞法作用域的查找混合使用時(shí),一定要提醒自己,這是無(wú)法實(shí)現(xiàn)的。

1.2 this到底是什么

? ? ? ?this 是在\color{red}{運(yùn)行時(shí)進(jìn)行綁定的},并不是在編寫(xiě)時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件。\color{green}{this 的綁定和函數(shù)聲明的位置沒(méi)有任何關(guān)系,只取決于函數(shù)的調(diào)用方式。}
? ? ? ?當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(有時(shí)候也稱(chēng)為執(zhí)行上下文)。這個(gè)記錄會(huì)包 含函數(shù)在哪里被調(diào)用(調(diào)用棧)、函數(shù)的調(diào)用方法、傳入的參數(shù)等信息。\color{red}{this} 就是記錄的其中一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過(guò)程中用到。

2 調(diào)用位置

? ? ? ?調(diào)用位置就是函數(shù)在代碼中\color{red}{被調(diào)用的位置}(而不是聲明的位置)。只有仔細(xì)分析調(diào)用位置才能回答這個(gè)問(wèn)題:這個(gè) this 到底引 用的是什么?
? ? ? ?尋找調(diào)用位置,最重要的是要分析調(diào)用棧(就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù))。

<script type="text/javascript">
function baz() {   
 // 當(dāng)前調(diào)用棧是:baz  ----------------------------2
 // 因此,當(dāng)前調(diào)用位置是全局作用域 
    console.log( "baz" );
    bar(); // <-- bar 的調(diào)用位置
}
function bar() { 
    // 當(dāng)前調(diào)用棧是 baz -> bar  ---------------------------- 3
    // 因此,當(dāng)前調(diào)用位置在 baz 中 
    console.log( "bar" );
    foo(); // <-- foo 的調(diào)用位置
}
function foo() {
// 當(dāng)前調(diào)用棧是 baz -> bar -> foo  ----------------------------4
 // 因此,當(dāng)前調(diào)用位置在 bar 中
    console.log( "foo" );
} 
baz(); // <-- baz 的調(diào)用位置         -----------------1    -------------5
</script>

? ? ? ?另一個(gè)查看調(diào)用棧的方法 是使用瀏覽器的調(diào)試工具。絕大多數(shù)現(xiàn)代桌面瀏覽器都內(nèi)置了開(kāi)發(fā)者工具, 其中包含 JavaScript 調(diào)試器。
? ? ? ?可以在工具中給 foo() 函數(shù)的 第一行代碼設(shè)置一個(gè)斷點(diǎn),或者直接在第一行代碼之前插入一條 debugger; 語(yǔ)句。運(yùn)行代碼時(shí),調(diào)試器會(huì)在那個(gè)位置暫停,同時(shí)會(huì)展示當(dāng)前位置的函數(shù)調(diào)用列表,這就是你的調(diào)用棧。因此,如果你想要分析 this 的綁定,使用開(kāi)發(fā)者工具得到調(diào)用棧,然后找到棧中第二個(gè)元素,這就是真正的調(diào)用位置。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • this 什么是this,其實(shí)你可以理解為它類(lèi)似一個(gè)指針 在瀏覽器環(huán)境中,全局作用域下,this指的是window...
    hhooke閱讀 273評(píng)論 0 0
  • this全面解析 調(diào)用位置 在理解 this 的綁定過(guò)程之前,首先要理解調(diào)用位置:調(diào)用位置就是函數(shù)在代碼中被調(diào)用的...
    后發(fā)而先制閱讀 492評(píng)論 1 0
  • 從學(xué)習(xí)前端開(kāi)始已經(jīng)大概要兩個(gè)月了,這幾天突然發(fā)現(xiàn)this并沒(méi)有想想中這么簡(jiǎn)單,之前很長(zhǎng)一段時(shí)間對(duì)于this的認(rèn)識(shí)停...
    悲歡自飲丶閱讀 362評(píng)論 0 0
  • this 關(guān)鍵字是 JavaScript 中最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在所有函數(shù)的作用域...
    后發(fā)而先制閱讀 395評(píng)論 0 0
  • this是什么 在函數(shù)運(yùn)行時(shí),基于調(diào)用位置的條件自動(dòng)生成的內(nèi)部對(duì)象,可以理解為動(dòng)態(tài)綁定對(duì)象到this上。 需要強(qiáng)調(diào)...
    烈風(fēng)裘閱讀 536評(píng)論 0 0

友情鏈接更多精彩內(nèi)容