js普通函數和箭頭函數的this(全網最容易理解)

最近在被箭頭函數與普通函數的區別的時候,有一個很是重要的區別就是this指向問題。自己筆者比較笨的那種,因此下面我都理解,全網的程序員都應該沒問題。說重點。。。程序員

普通函數的this

首先咱們來搞明白普通函數的this指向問題:windows

const obj = {
    bg:function(){
        console.log(this)    
    }
}
obj.bg() //obj
var dbl = obj.bg
dbj() //windows
複製代碼

上面代碼,obj對象裏面有一個bg的普通函數屬性,第一行執行obj.bg(),函數裏面的this指向obj這個對象。 第二行var dbl = obj.bg只作了賦值,並無執行,也就說如今dbl只是一個普通函數, 第三行執行dbl,此時普通函數裏面的this指向window。 因此上述總結:app

  • 1.普通函數最終指向調用它的對象,也就是說誰調用就指向誰。
  • 2.沒有被對象調用的函數默認指向window
function test(){
    console.log(this)
}
test()     //windows
new test() //test對象
test.call({id:1}) // {id:1}對象 
複製代碼

test是一個普通的構造函數,第一行執行此時普通函數裏面的this指向window,符合上述觀點,第二行new一個實例此時的this指向test的對象,這裏有些小夥伴比較蒙了,不是說好的誰調用指向誰嗎?怎麼回事,那是咱們不夠了解new到底作了什麼事。new關鍵字:1.建立了一個新的對象。2.將這個新的對象的__proto__指向了構造函數對象prototype對象。3.把構造函數的this指向這個新的對象而且執行,例如:test.call(newobj)。4.返回新的對象。這個樣一來咱們就明白執行實例化一個構造函數new test() 爲何指向test對象了。可是這不是我想表達的重點,咱們再看第三行test.call({id:1}),call方法你們都很熟吧,就是用來改變this指針的函數,而且執行這個構造函數(相應的還有bind、apply函數)。那麼這樣一來同一個構造函數,不一樣的調用方式,this指向的對象也是不同的。 因此上述總結:函數

  • 3.在函數沒有調用的時候this的指向是沒法肯定的,也就是說普通函數的this是在執行的時候肯定的。

箭頭函數的this

再接着說剪頭函數,其實箭頭函數沒有this,必須經過查找做用域鏈查找決定值。ui

const obj = {
    bg:() => {
        console.log(this)    
    }
}
obj.bg() //windows
複製代碼

例子中的剪頭函數bg的在obj調用函數的時候,this對obj對象沒有綁定做用它會沿着做用域鏈往上找,再上層做用域是window因此輸出結果是window;也就是說箭頭函數沒有this,它的this取決於做用域鏈上的this。 在這裏筆者有一個誤區,就是總覺得bg的箭頭函數上一層做用域是obj這個對象的塊級做用域,其實bg是obj的一個屬性,他們應該是同一級的做用域,我來換種寫就可理解了const obj.bg = ()=> {}這樣上層做用域就是window( 這裏我仍是要很是感謝筆者的同窗X幫我從坑中解救出來,哈哈哈)this

function test1(){
    return function(){
    console.log(this)
    }
}
var Test1 = new test1();  Test1() //windows

function test2(){
    return ()=>{
    console.log(this)
    }
}
var Test2 = new test2();  Test2() //Test2
複製代碼

剪頭函數的特殊本質就是函數中的this沒有綁定做用,或者能夠這樣說:剪頭函數中的this其實始終指向的是函數定義時的this的指向而非執行時的。spa

相關文章
相關標籤/搜索