首先複習下普通函數裏的this指向:函數
1 function test(){ 2 console.log(this) 3 } 4 test()
你會秒殺的毫無疑問的回答:window,針對普通函數:誰調用了函數 函數裏的this就指向誰,test()等價於window.test(),因此是windowthis
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 console.log(this.name) 6 } 7 } 8 o.getname()
這個是普通函數,誰調用了函數 函數裏的this就指向誰,o.getname(),調用這個getname函數的是o這個對象,這個o對象下面有name:"innername",因此打印出的是 "innername"spa
怎麼還不見ES6裏的箭頭函數呢?別急立刻登場:看我變身code
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:()=>{ 5 console.log(this.name) 6 } 7 } 8 o.getname()
哇,箭頭函數出來了,o.getname()執行後,由於箭頭函數坐鎮,我不敢輕易的說,由於調用getname()的是o對象,因此this指向o對象,哦NO,但是人家不是普通函數,人家是箭頭函數,哪就猜相反的那個var name="outername",它會打印外面的那個name("outername"),恭喜你,答對了,緣由下面會講解。對象
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 return ()=>this.name 6 7 } 8 } 9 console.log(o.getname()())
箭頭函數繼續出現,那麼這個會打印出什麼呢?不想猜的我直接敲出代碼打印出來答案:"innername",爲何?箭頭函數的this對象:就是定義時所在的對象,而不是使用時所在的對象,也就是根據外層(函數或者全局)做用域來決定this,再最後個例子一併總結.blog
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 setTimeout(()=>console.log(this.name),1000) 6 7 } 8 } 9 o.getname()
待我先總結完後本身能夠先去猜下沒有給出答案的答案.作用域
總結:get
普通函數this指向:誰調用了函數 函數裏的this就指向誰io
箭頭函數的this指向:就是定義時所在的對象,而不是使用時所在的對象,也就是根據外層(函數或者全局)做用域來決定thisconsole
調用的函數類型:
①箭頭函數:this指向window
②普通函數:this指向調用這個普通函數的對象,可能這個普通函數裏有箭頭函數,否管它,即便這個普通函數裏有箭頭函數,這個箭頭函數的this依舊是調用這個普通函數的對象
小結以上調用的函數是普通函數缺內嵌箭頭函數的例子:
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 return ()=>this.name 6 7 } 8 } 9 console.log(o.getname()())
1 var name="outername" 2 var o={ 3 name:"innername", 4 getname:function(){ 5 setTimeout(()=>console.log(this.name),1000) 6 7 } 8 } 9 o.getname()
this
對象的指向是可變的,可是在箭頭函數中,它是固定的。
1 function foo() { 2 setTimeout(() => { 3 console.log('id:', this.id); 4 }, 100); 5 } 6 7 var id = 21; 8 9 foo.call({ id: 42 }); 10 // id: 42
上面代碼中,setTimeout
的參數是一個箭頭函數,這個箭頭函數的定義生效是在foo
函數生成時,而它的真正執行要等到 100 毫秒後。若是是普通函數,執行時this
應該指向全局對象window
,這時應該輸出21
。可是,箭頭函數致使this
老是指向函數定義生效時所在的對象(本例是{id: 42}
),因此輸出的是42
。
但願此篇認清ES6箭頭函數裏的this指向,對你有用。