this到底是什么邻梆?
this是在運行的進行綁定的,并不是編寫時綁定的恩闻。他的上下文取決于函數(shù)調(diào)用的各種環(huán)境葫录。this的綁定和函數(shù)聲明的位置沒有任何關系,只取決與函數(shù)的調(diào)用方式赶熟。
調(diào)用位置
每個函數(shù)的this是在函數(shù)調(diào)用時綁定的瑰妄,完全取決于函數(shù)的調(diào)用位置。而不是聲明的位置
綁定規(guī)則
1.默認綁定
如果使用非嚴格模式钧大,this默認指向全局對象(window);嚴格模式(strict mode),則不能將全局對象用于默認綁定翰撑,因此this會綁定到undefined;
2.隱式綁定
考慮調(diào)用位置是否有上下文對象
對象屬性引用鏈中只有在上一層或者說最后一層在調(diào)用位置中起作用
缺點:1有時候隱式綁定的函數(shù)會丟失綁定對象罩旋;
? ? ? ? ? 2.調(diào)用回調(diào)函數(shù)的函數(shù)可能會修改this
3.顯示綁定
call(...)和apply(...),第一個參數(shù)是對象啊央,給this準備的,接著在調(diào)用函數(shù)時將其綁定到this;兩者區(qū)別在第二個參數(shù)涨醋,call要求第二個參數(shù)必須一個一個傳入瓜饥,apply第二個參數(shù)以數(shù)組形式傳入;
bind(...)他會把你指定的參數(shù)設置為this的上下文浴骂,并調(diào)用原始函數(shù)
缺點:1.會大大降低函數(shù)的靈活性乓土;
? ? ? ?2. 一旦綁定,不可在修改this的值
new綁定
使用new來調(diào)用函數(shù)(發(fā)生構造函數(shù))
1.創(chuàng)建(構造)一個全新的對象
2.這個新對象被執(zhí)行[[Prototype]]鏈接
3.這個新對象綁定到函數(shù)調(diào)用的this
4.如果函數(shù)沒有返回其他對象溯警,那么new表達式中的函數(shù)會自動返回這個新對象
優(yōu)先級
默認綁定<隱式綁定<new綁定<顯示綁定
綁定例外
1.如果你把null或者undefined作為this的綁定對象傳入call趣苏,apply,bind梯轻,這些值在調(diào)用的時會被忽略食磕。實際應用是默認值
2.間接引用
3.軟綁定,給默認的綁定指定一個全局對象和undefined以為的值喳挑,那就可以實現(xiàn)和硬綁定相同的效果彬伦,同時保留或者顯示綁定修改的this的能力
賦值表達式p.foo=b.foo的返回值是目標的引用,因此調(diào)用位置是foo而不是p.foo()或者o.foo()伊诵。簡而言之就是函數(shù)的調(diào)用位置決定单绑。
this語法
es6箭頭函數(shù)不使用this的四種標準規(guī)則,而是根據(jù)外層(函數(shù)或者全局)作用域來決定this曹宴。箭頭函數(shù)一單綁定搂橙。無法修改
小結
如果要判斷一個運行中函數(shù)的this綁定,就需要找到這個函數(shù)的直接調(diào)用位置笛坦。找到之后就可以按照下面四條規(guī)則來判斷this的綁定對象
1.由call区转,apply唯袄,bind調(diào)用?綁定到指定對象
2.new調(diào)用?綁定到新創(chuàng)建的對象
3.由上下文對象調(diào)用蜗帜?綁定到那個上下文對象
4.默認:嚴格模式下綁定到undefined恋拷,反之綁定到全局對象。
es6中的箭頭并不會使用四條標準的綁定規(guī)則厅缺。箭頭函數(shù)會繼承外層函數(shù)調(diào)用的this綁定蔬顾。箭頭函數(shù)一但綁定無法修改
函數(shù)在哪調(diào)用,this就綁定到該對象
參考資料《你不知道的JavaScript》
記得喜歡點喜歡喲湘捎,你的喜歡是我繼續(xù)的最大動力來源吶诀豁。
如果恰好你也是前端編程朋友,我們可以相互關注窥妇,相互學習舷胜,相約在前端