前言
關(guān)于javascript中的this究竟指的是什么杠巡,已經(jīng)有很多文章寫過庇楞,在這里總結(jié)一下憋活。
書中的重要觀點(diǎn)
- this的指向并不是指向函數(shù)本身或函數(shù)的詞法作用域潘明;
- this的值是在函數(shù)調(diào)用時(shí)才綁定的祠汇,創(chuàng)建時(shí)并沒有綁定this;
- this的指向取決于在何處被調(diào)用瓢捉。
函數(shù)的調(diào)用模式
在說this的綁定方式之前笨忌,我們先談?wù)労瘮?shù)的調(diào)用蓝仲。調(diào)用一個(gè)函數(shù)時(shí),會(huì)暫停當(dāng)前函數(shù)的執(zhí)行傳遞控制權(quán)和參數(shù)給調(diào)用的函數(shù)官疲。除了函數(shù)聲明時(shí)定義的形參袱结,函數(shù)還會(huì)接受兩個(gè)附加的參數(shù): arguments和this,arguments即函數(shù)的入?yún)⑼举欤瑃his的指向和函數(shù)的調(diào)用模式有關(guān)垢夹。
在javascript中,函數(shù)的調(diào)用模式一般分為四種:方法調(diào)用模式维费、函數(shù)調(diào)用模式果元、構(gòu)造器調(diào)用模式、apply調(diào)用模式犀盟。
- 方法調(diào)用模式
當(dāng)一個(gè)函數(shù)作為一個(gè)對(duì)象的一個(gè)屬性時(shí)而晒,我們稱之為方法。當(dāng)一個(gè)方法被調(diào)用時(shí)阅畴,函數(shù)的this指向調(diào)用該方法的對(duì)象倡怎。 - 函數(shù)調(diào)用模式
當(dāng)一個(gè)函數(shù)不作為一個(gè)對(duì)象的屬性時(shí),就是我們最常見的函數(shù)調(diào)用模式贱枣。在這種情況下如果是非嚴(yán)格模式(non-strict mode)下運(yùn)行則this指向全局對(duì)象监署,瀏覽器下為window,node模式下為global纽哥。 - 構(gòu)造器調(diào)用模式
當(dāng)一個(gè)函數(shù)被當(dāng)做“構(gòu)造函數(shù)”(嚴(yán)格來講構(gòu)造函數(shù)和普通函數(shù)沒有區(qū)別)焦匈,當(dāng)我們用關(guān)鍵字new來以“構(gòu)造函數(shù)”為藍(lán)圖來創(chuàng)建一個(gè)對(duì)象時(shí),函數(shù)中的this就會(huì)指向創(chuàng)建的對(duì)象實(shí)例昵仅。 - apply調(diào)用模式
apply方法讓我們構(gòu)建一個(gè)參數(shù)數(shù)組傳給需要調(diào)用的函數(shù),apply接受兩個(gè)參數(shù),第一個(gè)為this綁定的值摔笤,第二個(gè)即需要傳入的參數(shù)數(shù)組够滑。apply方法可以顯式地綁定this的值,類似的還有bind和call吕世,需要注意地是彰触,bind方法是返回一個(gè)新的函數(shù)。
this判斷規(guī)則
- 看是否由 new 調(diào)用命辖?是則綁定到新創(chuàng)建的對(duì)象况毅。
- 再看是否由 call 或者 apply (或者 bind )調(diào)用?綁定到指定的對(duì)象尔艇。
- 看函數(shù)是否為上下文對(duì)象的方法調(diào)用尔许?是則綁定到那個(gè)上下文調(diào)用方法的對(duì)象。(特點(diǎn)是用"."或者"[ ]"來調(diào)用)
- 默認(rèn)函數(shù)調(diào)用:在嚴(yán)格模式下綁定到 undefined 终娃,否則綁定到全局對(duì)象味廊。
ES6 中的箭頭函數(shù)并不會(huì)使用四條標(biāo)準(zhǔn)的綁定規(guī)則,而是根據(jù)當(dāng)前的詞法作用域來決定this 棠耕,具體來說余佛,箭頭函數(shù)會(huì)繼承外層函數(shù)調(diào)用的 this 綁定(無論 this 綁定到什么)。這其實(shí)和 ES6 之前代碼中的 self = this 機(jī)制一樣窍荧。
tips:
- 回調(diào)函數(shù)丟失 this 綁定是非常常見的辉巡,如settimeout();
- 一些流行的JavaScript 庫中事件處理器常會(huì)把回調(diào)函數(shù)的 this 強(qiáng)制綁定到觸發(fā)事件的 DOM 元素上蕊退。