摘要:關(guān)于的指向問題算的上是中的一個(gè)十分重要的問題了。首先,的指向問題可以用一句話總結(jié)就是總是指向調(diào)用的對(duì)象,也就是說指向誰與函數(shù)聲明的位置沒有關(guān)系,只與調(diào)用的位置有關(guān)。此外注意幾種特殊情況,特別是中的箭頭函數(shù)。
關(guān)于this的指向問題算的上是js中的一個(gè)十分重要的問題了。今天把這個(gè)問題總結(jié)下,加深下自己對(duì)this的理解。
首先,this的指向問題可以用一句話總結(jié)就是:this總是指向調(diào)用的對(duì)象,也就是說this指向誰與函數(shù)聲明的位置沒有關(guān)系,只與調(diào)用的位置有關(guān)。這是判斷this的一個(gè)大體原則,而具體的小原則按照優(yōu)先級(jí)的不同大致可以分為以下幾點(diǎn):
new方式是優(yōu)先級(jí)最高的一種調(diào)用方式,也就是說只要是出現(xiàn)new方式來調(diào)用一個(gè)函數(shù),this肯定會(huì)指向new調(diào)用函數(shù)新創(chuàng)建的對(duì)象。
function() thisTo(a){ this.a=a; } var data=new thisTo(2); //在這里進(jìn)行了new綁定 console.log(data.a); //22.顯式綁定
顯示綁定指的是通過call()和apply()方法對(duì)函數(shù)進(jìn)行的調(diào)用,對(duì)this影響的優(yōu)先級(jí)僅次于new綁定。
function thisTo(){ console.log(this.a); } var data={ a:2 }; thisTo.call(data)); //23.隱式綁定
隱式綁定是指通過對(duì)象的屬性進(jìn)行添加,從而調(diào)用this所在函數(shù),該方式的優(yōu)先級(jí)在顯示綁定之后。
function thisTo(){ console.log(this.a); } var data={ a:2, foo:thisTo //通過屬性引用this所在函數(shù) }; data.foo(); //24.默認(rèn)綁定
默認(rèn)綁定是指當(dāng)上面這三條綁定規(guī)則都不符合時(shí)采用的綁定規(guī)則,默認(rèn)綁定會(huì)把this默認(rèn)綁定到全局對(duì)象中,是優(yōu)先級(jí)最低的綁定規(guī)則。
function thisTo(){ console.log(this.a); } var a=2; //a是全局對(duì)象的一個(gè)同名屬性 thisTo(); //2二.this綁定的特殊情況 1.隱式丟失
當(dāng)進(jìn)行隱式綁定時(shí),如果進(jìn)行一次引用賦值或者傳參操作,會(huì)造成this的丟失,從而最后將this綁定到全局對(duì)象中去。
1.1 引用賦值丟失
function thisTo(){ console.log(this.a); } var data={ a:2, foo:thisTo //通過屬性引用this所在函數(shù) }; var a=3;//全局屬性 var newData=data.foo; //這里進(jìn)行了一次引用賦值 newData(); // 3
原理:因?yàn)閚ewData實(shí)際上引用的是foo函數(shù)本身,跟data對(duì)象沒有任何關(guān)系,data對(duì)象只是一個(gè)中間橋梁。而newData就是一個(gè)本身不帶a屬性的對(duì)象,自然最后只能把a(bǔ)綁定到全局對(duì)象上了。
1.2傳參丟失
function thisTo(){ console.log(this.a); } var data={ a:2, foo:thisTo //通過屬性引用this所在函數(shù) }; var a=3;//全局屬性 setTimeout(data.foo,100);// 3
原理:setTimeout(fn,delay) { fn(); } 實(shí)際上fn是一個(gè)參數(shù)傳遞的引用(fn=data.foo),與引用丟失的原理一樣
1.3 Function.prototype.bind()
為了解決隱式丟失的問題,ES5提供了bind方法,bind()會(huì)返回一個(gè)硬編碼的新函數(shù),它會(huì)把參數(shù)設(shè)置為this的上下文并調(diào)用原始函數(shù)。
function thisTo(){ console.log(this.a); } var data={ a:2 }; var a=3; var bar=thisTo.bind(data); console.log(bar()); //22.間接引用
間接引用是指一個(gè)定義對(duì)象的方法引用另一個(gè)對(duì)象存在的方法,這種情況下會(huì)使得this進(jìn)行默認(rèn)綁定。
function thisTo(){ console.log(this.a); } var data={ a:2, foo:thisTo }; var newData={ a:3 } var a=4; data.foo(); //2 (newData.foo=data.foo)() //4
原理:newData.foo=data.foo的返回值是目標(biāo)函數(shù)的引用,因此調(diào)用的位置實(shí)際上是foo(),根據(jù)之前的隱式丟失里面說的原則,這里會(huì)應(yīng)用默認(rèn)綁定。
3.ES6箭頭函數(shù)ES6的箭頭函數(shù)在this這塊是一個(gè)特殊的改進(jìn),箭頭函數(shù)使用了詞法作用域取代了傳統(tǒng)的this機(jī)制,所以箭頭函數(shù)無法使用上面所說的這些this優(yōu)先級(jí)的原則,注意的是在箭頭函數(shù)中,是根據(jù)外層父親作用域來決定this的指向問題。
function thisTo(){ setTimeout(function(){ console.log(this.a); },100); } var obj={ a:2 } var a=3; thisTo.call(obj); //3
不用箭頭函數(shù),發(fā)生隱式丟失,最后的this默認(rèn)綁定到全局作用域,輸出3。
function thisTo(){ setTimeout(()=>{ console.log(this.a); },100); } var obj={ a:2 } var a=3;加粗文字 thisTo.call(obj); //2
用了箭頭函數(shù),不會(huì)發(fā)生隱式丟失,this綁定到外層父作用域thisTO(),thisTo的被調(diào)用者是obj對(duì)象,所以最后的this到obj對(duì)象中,輸出2。
如果不用箭頭函數(shù)實(shí)現(xiàn)相同的輸出,可以采用下面這種方式:
function thisTo(){ var self=this; //在當(dāng)前作用域中捕獲this setTimeout(function(){ console.log(self.a); //傳入self代替之前的this },100); } var obj={ a:2 } var a=3; thisTo.call(obj); //2三.總結(jié):
this的綁定機(jī)制,就是要找到這個(gè)函數(shù)的直接調(diào)用位置,然后應(yīng)用綁定的四條規(guī)則,當(dāng)出現(xiàn)滿足多個(gè)規(guī)則時(shí),按照優(yōu)先級(jí)的高低決定最終的綁定規(guī)則。此外注意幾種特殊情況,特別是ES6中的箭頭函數(shù)。
四.參考書籍:你不知道的JavaScript上卷
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82496.html
摘要:下面只探討在瀏覽器中的指向,有興趣的也可以把后面的例子在中跑一下。 我們知道js中有個(gè)全局對(duì)象就是window,如果在頂層聲明一個(gè)變量如 var a=1 //就相當(dāng)于window.a=1 同時(shí)有了node以后,js也可以在服務(wù)端運(yùn)行了,官方解釋為Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境。通俗說node是一個(gè)支持js語法的容器,直接寫js就可...
摘要:是什么這個(gè)單詞是一個(gè)代詞,所以應(yīng)該是指代某些東西搞清楚的關(guān)鍵之處,就是要搞清楚指代了什么那么到底指代了什么呢就像你平時(shí)指著一個(gè)蘋果說指著一個(gè)香蕉說同樣,也會(huì)因?yàn)榍闆r的不同而不同在中按照常規(guī)理解,的值是什么取決于函數(shù)如何被調(diào)用然而,的值是什么 1. this是什么 this這個(gè)單詞是一個(gè)代詞,所以this應(yīng)該是 指代某些東西搞清楚this的關(guān)鍵之處,就是要搞清楚this指代了什么 那么t...
摘要:中指向問題一直是個(gè)坑,之前一直是懵懵懂懂的,大概知道一點(diǎn),但一直不知道各種情況下指向有什么區(qū)別,今天親自動(dòng)手測(cè)試了下的指向。這就是我關(guān)于學(xué)習(xí)的總結(jié),希望能給需要的人點(diǎn)幫助,然后有啥不足希望有大神能指點(diǎn)出來。 js中this指向問題一直是個(gè)坑,之前一直是懵懵懂懂的,大概知道一點(diǎn),但一直不知道各種情況下指向有什么區(qū)別,今天親自動(dòng)手測(cè)試了下this的指向。 1.在對(duì)象中的this對(duì)象中的t...
摘要:中指向問題一直是個(gè)坑,之前一直是懵懵懂懂的,大概知道一點(diǎn),但一直不知道各種情況下指向有什么區(qū)別,今天親自動(dòng)手測(cè)試了下的指向。這就是我關(guān)于學(xué)習(xí)的總結(jié),希望能給需要的人點(diǎn)幫助,然后有啥不足希望有大神能指點(diǎn)出來。 js中this指向問題一直是個(gè)坑,之前一直是懵懵懂懂的,大概知道一點(diǎn),但一直不知道各種情況下指向有什么區(qū)別,今天親自動(dòng)手測(cè)試了下this的指向。 1.在對(duì)象中的this對(duì)象中的t...
閱讀 1281·2021-11-17 09:33
閱讀 1754·2021-09-09 11:53
閱讀 3230·2021-09-04 16:45
閱讀 1407·2021-08-17 10:12
閱讀 2399·2019-08-30 15:55
閱讀 1784·2019-08-30 15:53
閱讀 2415·2019-08-30 15:52
閱讀 2564·2019-08-29 18:41