this的指向已經是乙個老生常談的問題,每逢面試都要去複習複習,近來鞏固js的基礎,決心徹底掌握這個知識點,一勞永逸。說明一下,為了不影響大家的思考過程,下面的**都不會去注釋答案,想知道答案,只需要去控制台執行一下。
四類場景逐一擊破
首先,分析this的指向共有四種型別,在分析之前,我們首先帶好兩個錦囊:
1、函式被呼叫時(即執行時)才會確定該函式內this的指向。因為在函式中this與arguments是兩個特殊的變數,在函式被呼叫時才會取得它們,而且搜尋這兩個變數時只會在活動物件範圍裡面去搜。(有關活動物件與變數物件的知識,請移步到js 中的活動物件 與 變數物件 什麼區別?)
2、要確定函式中this的指向,必須先找到該函式被呼叫的位置。
認準第一種test()
形式
var a = 1
function test ()
test()
直接不帶任何引用形式去呼叫函式,則this會指向全域性物件,因為沒有其他影響去改變this,this預設就是指向全域性物件(瀏覽器是window,node中是global)的。這個結論是在非嚴格模式的情況下,嚴格模式下這個this其實是undefined的。
認準第二種***.test()
形式
var a = 1
function test ()
var obj =
obj.test()
這種形式對比起第一種,很明顯
test()
已經是名花有主的了!看清楚,是誰呼喚的test()
?沒錯,就是obj,所以this的指向就不言而喻了。一句話,誰去呼叫這個函式的,這個函式中的this就繫結到誰身上。
var a = 1
function test ()
var obj =
var obj0 =
obj0.obj.test()
即使是這種串串燒的形式,結果也是一樣的,
test()
中的this只對直屬上司(直接呼叫者obj)負責。再來看乙個綜合點的例子:
var a = 1
function test ()
var obj =
var testcopy = obj.test
testcopy()
嗯,聰明的你一定想到,換了個名字就能騙到我了!?雖然經過了一波改名換姓,但本質上還不是
obj.test()
嘛!結果一定和上面一樣!唔,請f12在控制台試試,竟然……其實這裡並不需要去思考什麼,按照我們的套路,我們就認函式調時的樣子,有沒有看到最後呼叫的時候跟第一種情況一毛一樣?我再介紹乙個場景大家一定不會覺得陌生:
var a = 1
function test ()
var obj =
settimeout(obj.test)
你可以意淫一下settimeout的本質,是不是相當於有乙個settimeout函式,接收兩個引數:
function settimeout (fn, time)
看到怎樣呼叫你傳進來的函式了嗎!?再想想我們第一種形式的標題認準第一種test()
形式。
形式看了上面兩種形式之後,你可能會想,我非常討厭上面那些矯情的扭扭捏捏的九曲十八彎的呼叫方式,讓人毫無安全感,我要我自己指定this的指向,我要勝天半子!沒問題,我的**我做主:
var a = 1
function test ()
var obj =
var testcopy = obj.test
testcopy.call(obj)
認準第四種
newtest()
形式
終於到了最後一種形式了,這種形式比較好認,因為有標誌性的new:
var a = 1
function test (a)
var b = new test(2)
console.log(b.a)
new這個操作符其實是new了乙個新物件出來,而被new的test我們稱為建構函式,我們可以在這個建構函式裡定義一下將要到來的新物件的一些屬性。那麼在建構函式裡,我們怎樣去描述這個還未出生的新物件呢?沒錯,就是用this。所以建構函式裡的this指的就是將要被new出來的新物件。
one more thing
感謝大家看到這裡,但還要說最後一種形式。等等,不是說好的只有四種形式嗎!稍安勿躁,正常套路下確實只有上面四種,但是有個東西別忘了,就是大家最喜歡的箭頭函式。
var a = 1
var test = () =>
var obj =
obj.test()
來,往上翻一下我們的第乙個錦囊,「函式被呼叫時(即執行時)才會確定該函式內this的指向。」現在函式這兩個字要加個詞修飾一下,變成普通函式(非箭頭函式)才能區別於箭頭函式。箭頭函式中的this在函式定義的時候就已經確定,它this指向的是它的外層作用域this的指向。
最後我們最後還要說:「到此為止,真的沒有了。」
揚長而去。
關注:前端教程,一起提公升前端技術!
好看」 行不行
不要再問我this的指向問題了
this的指向已經是乙個老生常談的問題,每逢面試都要去複習複習,近來鞏固js的基礎,決心徹底掌握這個知識點,一勞永逸。說明一下,為了不影響大家的思考過程,下面的 都不會去注釋答案,想知道答案,只需要去控制台執行一下。首先,分析this的指向共有四種型別,在分析之前,我們首先帶好兩個錦囊 1.函式被呼...
別再問我ConcurrentHashMap了
以下concurrenthashmap以jdk8中為例進行分析,concurrenthashmap是乙個執行緒安全 基於陣列 鍊錶 或者紅黑樹 的kv容器,主要特性如下 concurrenthashmap預設陣列長度16,map最大容量為maximum capacity 1 30。建立concurr...
拜託,面試別再問我跳表了!
跳表是乙個隨機化的資料結構,實質就是一種可以進行二分查詢的有序鍊錶。跳表在原有的有序鍊錶上面增加了多級索引,通過索引來實現快速查詢。跳表不僅能提高搜尋效能,同時也可以提高插入和刪除操作的效能。考慮乙個有序鍊錶,我們要查詢3 7 17這幾個元素,我們只能從頭開始遍歷鍊錶,直到查詢到元素為止。上述這個鍊...