這篇文章主要介紹“JS中的this指向問題詳細(xì)介紹”,在日常操作中,相信很多人在JS中的this指向問題詳細(xì)介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JS中的this指向問題詳細(xì)介紹”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供婺源網(wǎng)站建設(shè)、婺源做網(wǎng)站、婺源網(wǎng)站設(shè)計、婺源網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、婺源企業(yè)網(wǎng)站模板建站服務(wù),10多年婺源做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
1. 什么是 this?
什么是 this呢?上邊我們說 this是一個對象,是個啥對象?咱們就來動手敲代碼打印一下。我們最常見的 this是在一個函數(shù)中, JS 的函數(shù)調(diào)用有兩種方式,一種是我們直接調(diào)用,另外一種就是通過 new 的方式來調(diào)用,我們通過兩種方式來打印一下 this值是否相同?。
控制臺輸出如下:
吆喝?咦?雖然都是在函數(shù)中,咋打印出來的不一樣呢?直接通過函數(shù)調(diào)用的方式打印出來的 this指向的是全局變量Window;通過new的方式調(diào)用的函數(shù)當(dāng)做為構(gòu)造函數(shù),為了能夠創(chuàng)建一個實例對對象,它的 this值指向生成的實例對象。
那我們通過上邊的一頓亂操作,知道了 this是一個對象,但是我們不同的操作 this指向的對象是不相同的。寫到這里,知道 this是個什么東西就可以了,下面我們再慢慢深入 this原理。
2. 如何判斷 this?
既然我們知道 this 是什么東西了,但是怎么判斷 this的值呢?也是我們上邊沒有解決的問題。this的指向有三種情況,只要理解了這三種情況,也不用死記硬背,判斷 this如魚得水,在面試中給面試官講的滾瓜爛熟。
三種 this指向情況:
(1) 對象調(diào)用,this 指向該對象(前邊誰調(diào)用 this 就指向誰)。
對于第一種情況,通過對象調(diào)用的方式,this指向誰?要想一探究竟,必須動手實踐一下。小鹿,上代碼,好嘞~。
控制臺打?。?/p>
我們通過親手測試,我們發(fā)現(xiàn) this的指向就是 obj,所以我們總結(jié)歸納為誰調(diào)用了函數(shù), this就指向誰,很簡單吧,我們繼續(xù)向下看。
(2) 直接調(diào)用的函數(shù),this 指向的是全局 window 對象。
其實這也屬于第一種情況,如果我們直接在全局函數(shù)調(diào)用了函數(shù),其實是全局的對象 Window調(diào)用了函數(shù),根據(jù)第一條我們得出的結(jié)論,誰調(diào)用的函數(shù),this就指向誰,想必你已經(jīng)知道了第二種情況 this指向的就是 Window。
(3) 通過 new 的方式,this 永遠(yuǎn)被綁定在新創(chuàng)建的對象上,任何方式都改變不了 this 的指向。
第三種方式剛才我們也測試過了,this指向的是指向生成的對象實例,很多好奇的小伙伴就會問小鹿,很好奇 new的內(nèi)部實現(xiàn),到底做了什么,其實沒什么復(fù)雜的,不告訴你估計你也通過上邊的兩個結(jié)論可以得出。
我們從的到的結(jié)果進(jìn)行反推,通過 new的方式 this 指向的是生成的對象實例,那我們猜測肯定內(nèi)部讓這個實例對象調(diào)用了函數(shù),所以 this 才指向生成的對象實例。
真實的情況是這樣子嗎?確實是,我們 new的過程,其實在內(nèi)部創(chuàng)建了一個空對象,然后將構(gòu)造函數(shù)傳入的參數(shù)和屬性掛在了這個空對象上,然后返回了這個對象。還涉及該空對象到原型鏈的的掛載,想要具體了解,可以自己探究下,這里不多說了。
擴(kuò)展:箭頭函數(shù)的 this 指向誰?
我們都知道 ES6 之后,為了使用函數(shù)更加方便,在項目中我們會使用箭頭函數(shù),書寫方式:
運(yùn)行程序,控制臺輸出:
我們可以得出結(jié)論,this在箭頭函數(shù)中失效了,因為這是由于箭頭函數(shù)沒有單獨的 this值。箭頭函數(shù)的 this與聲明所在的上下文相同。也就是說調(diào)用箭頭函數(shù)的時候,不會隱士的調(diào)用 this參數(shù),而是從定義時的函數(shù)繼承上下文。
有關(guān)箭頭函數(shù)這一點,一定要注意,面試的時候也會經(jīng)常給你刨坑哦!
3. 如何改變 this 的值?
我們對 this的指向已經(jīng)把它翻了個底朝天,但是不要傲嬌,需要自己找點有關(guān) this 的大廠面試題去做,這樣鞏固一下加深理解。
this可以指向不同的對象,我們想要改變 this有沒有辦法呢?有的,改變 this的方法共有三種,我們具體看看這三種方法之間的實現(xiàn)和區(qū)別,也是面試重點哦!
(1) call 方法
call方法用來改變 this的指向,具體咱們先看實例:
控制臺輸出如下:
(2) apply 方法
我們再來看apply方法,同樣舉個例子:
控制臺輸出如下:
我們發(fā)現(xiàn)輸出的值相同,我們先不比較兩者的區(qū)別是什么,我們繼續(xù)往下看bind函數(shù)。
(3) bind 方法
我們在用 bind函數(shù)舉個例子:
控制臺輸出如下:
(4) call、apply、bind 三者的區(qū)別是什么?
我們對于三者都進(jìn)行舉例運(yùn)行了,我們開始做總結(jié)歸納,我們先找找三者的共同點是什么?
共同點:
都能改變 this 指向,第一個傳遞的參數(shù)都是 this 指向的對象。
三者都采用的后續(xù)傳參的形式。
三者相同點表面上都能看出來,功能都是一樣的,但是對于不同點,就涉及到細(xì)節(jié)了,不知道你發(fā)現(xiàn)了沒有?
不同點:
call的傳參是單個傳遞的,而 apply后續(xù)傳遞的參數(shù)是數(shù)組形式,而 bind沒有規(guī)定,傳遞值和數(shù)組都可以。
call和 apply函數(shù)的執(zhí)行是直接執(zhí)行的,而 bind函數(shù)會返回一個函數(shù),然后我們想要調(diào)用的時候才會執(zhí)行。
你可能會有疑惑,小鹿,難道你就是這樣表面看出的嗎?雖然我們表面可以看得出,那不妨我們自己手寫一個 call、apply、和 bind的吧,看了源碼的實現(xiàn),你會覺得這三個函數(shù)也沒有什么難的。因為涉及到時間問題,我們就不展開講了,小鹿把代碼貼到下邊了,感興趣的可以研究一下。
手寫 call 函數(shù):
手寫 apply 函數(shù):
手寫 bind 函數(shù):
PS:如果我們使用上邊的方法改變箭頭函數(shù)的 this 指針,會發(fā)生什么情況呢?能否對齊進(jìn)行改變呢?
由于箭頭函數(shù)沒有自己的this指針,通過 call() 或 apply() 方法調(diào)用一個函數(shù)時,只能傳遞參數(shù)(不能綁定this),他們的第一個參數(shù)會被忽略。
到此,關(guān)于“JS中的this指向問題詳細(xì)介紹”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
當(dāng)前標(biāo)題:JS中的this指向問題詳細(xì)介紹
文章轉(zhuǎn)載:http://weahome.cn/article/jedpcs.html