首先來(lái)復(fù)習(xí)一下this的指向問(wèn)題吧僧须?
this只有在方法被調(diào)用的時(shí)候端考,才知道他的指向图仓,定義的時(shí)候是不知道的罐盔。
劃分為以下幾種:
對(duì)象里方法中的this指向調(diào)用他的對(duì)象。比如延時(shí)器方法setTimeout()救崔,在調(diào)用時(shí)(非嚴(yán)格模式)惶看,其內(nèi)部this指向?yàn)閣indow捏顺,因?yàn)閷?shí)際上它是window對(duì)象下的方法,即window.setTimeout()纬黎。
(所以這個(gè)時(shí)候?yàn)榱藢懟卣{(diào)方便草丧,可以用箭頭函數(shù)
注意:如果是很長(zhǎng)的調(diào)用,如:a.b.c() 那么在c中this的指向?yàn)樽詈蟮恼{(diào)用莹桅,即a.b這個(gè)對(duì)象昌执。使用call,apply后诈泼,this指向你傳入的對(duì)象懂拾,注意此時(shí)函數(shù)已經(jīng)被調(diào)用,this指向確定铐达。
使用new時(shí)岖赋,this指向構(gòu)造對(duì)象。 new 一個(gè)構(gòu)造函數(shù)時(shí)瓮孙,會(huì)發(fā)生4步操作:
如 let person1 = new Person()
第一步: 創(chuàng)建一個(gè)新的對(duì)象 obj
第二步: 將 obj 的constructor設(shè)置為其構(gòu)造函數(shù)唐断,并將 obj 的proto指向其構(gòu)造函數(shù)的prototype
第三步: 更改Person構(gòu)造函數(shù)中的this指向?yàn)閛bj,執(zhí)行Person函數(shù)
第四步: 把obj 給 return出去杭抠。這里有個(gè)注意點(diǎn)脸甘,return是默認(rèn)進(jìn)行的,無(wú)需在構(gòu)造函數(shù)里面寫偏灿。但如果在構(gòu)造函數(shù)里面寫了return且return的是簡(jiǎn)單數(shù)據(jù)類型丹诀,那么return的結(jié)果仍為新創(chuàng)建的對(duì)象 obj 。如果return出去的是一個(gè)復(fù)雜類型翁垂,那么return出去的將不會(huì)是新創(chuàng)建的對(duì)象 obj 铆遭。
箭頭函數(shù)指向誰(shuí)呢?
箭頭函數(shù)的this: 指向箭頭函數(shù)定義時(shí)所處的對(duì)象,而不是箭頭函數(shù)使用時(shí)所在的對(duì)象,默認(rèn)使用父級(jí)的this.
到這里基本就確定了什么時(shí)候不能用箭頭函數(shù)了沿猜,因?yàn)槲艺J(rèn)為箭頭函數(shù)最大的作用就是方便確定this作用域枚荣。
下面是幾個(gè)典型的例子不建議使用箭頭函數(shù)的地方:
一、使用addEventListener時(shí)不建議使用箭頭函數(shù)啼肩。
示例:
1橄妆、獲取dom對(duì)象 :
let domObj = document.getElementId('xx')
domObj.addEventListener('click', () => { console.log( this ) }, false)
根據(jù)上面的this指向可知,如果改為箭頭函數(shù)疟游,其內(nèi)部this會(huì)變成window呼畸,而不是domObj痕支,因此不推薦使用箭頭函數(shù)颁虐。
2、對(duì)象內(nèi)部聲明方法時(shí)卧须,不建議使用箭頭函數(shù)另绩,因?yàn)閠his會(huì)指向外部而不是調(diào)用它的那個(gè)對(duì)象:
示例:
let obj = {
fn: () => { console.log(this) } // window
}
3儒陨、在構(gòu)造函數(shù)的prototype上添加方法,不建議使用箭頭函數(shù):
Array.prototype.add = () => { console.log(this) } // window
4笋籽、Vue的生命周期鉤子函數(shù) :
其默認(rèn)指向當(dāng)前vm組件蹦漠,如果使用箭頭函數(shù)聲明,則會(huì)更改其指向车海。