這篇文章主要介紹了JavaScript This指向問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
創(chuàng)新互聯(lián)公司專(zhuān)注于企業(yè)全網(wǎng)營(yíng)銷(xiāo)推廣、網(wǎng)站重做改版、石臺(tái)網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5建站、成都做商城網(wǎng)站、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為石臺(tái)等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
各位小伙伴在面試中被面試官問(wèn)道this指向問(wèn)題一定不少吧,同時(shí)還被問(wèn)道apply,call和bind的用法區(qū)別,現(xiàn)在,就來(lái)簡(jiǎn)單的聊一聊this到底指向何方。
1.基本概念
MDN的官方解釋?zhuān)号c其他語(yǔ)言相比,函數(shù)的 this 關(guān)鍵字在 JavaScript 中的表現(xiàn)略有不同,此外,在嚴(yán)格模式和非嚴(yán)格模式之間也會(huì)有一些差別。在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了this的值。this不能在執(zhí)行期間被賦值,并且在每次函數(shù)被調(diào)用時(shí)this的值也可能會(huì)不同。
簡(jiǎn)而言之:
1.this指向的對(duì)象稱(chēng)為函數(shù)的上下文對(duì)象context;
2.this的指向取決于函數(shù)被調(diào)用方式
不管函數(shù)怎么調(diào)用的天花亂墜,我們只要記住這幾點(diǎn)即可清晰的找出this的指向。
2.小試牛刀
function foo(){ console.log(this); }
面試官問(wèn)你this指向哪里,當(dāng)然大聲回答不知道,原因:誰(shuí)調(diào)用指向誰(shuí),函數(shù)都沒(méi)被調(diào)用,確實(shí)不知道指向。
小結(jié):直接通過(guò)函數(shù)名來(lái)調(diào)用函數(shù),this指向全局變量window;通過(guò)對(duì)象.函數(shù)名調(diào)用函數(shù),this指向該對(duì)象。
3.DOM對(duì)象調(diào)用函數(shù)時(shí)this的指向問(wèn)題
1.通過(guò)選擇器選擇元素加事件屬性來(lái)綁定事件,this指向該DOM對(duì)象,例子如下:
document.getElementById('btn').onclick=function(){ console.log('click'); //click console.log(this); // }
2.直接在DOM標(biāo)簽中寫(xiě)事件,this指向window,我們可以通過(guò)吧this作為參數(shù)傳入方法中再使用,例子如下
html:
0
script:
// 操作方法
function modify(){
console.log(this); //window
}
因?yàn)檫@個(gè)時(shí)候是直接調(diào)用方法的,所以this指向全局window對(duì)象,那么問(wèn)題來(lái)了,我們想判斷我們點(diǎn)擊的是哪一個(gè)按鈕,應(yīng)該怎么做呢,我們可以把this的值作為參數(shù)傳入方法中再使用,例子如下。
html:
0
script:
// 操作方法
function modify(_this){
console.log(_this);
//
//
}
4.對(duì)象中this的指向問(wèn)題
先看一個(gè)簡(jiǎn)單的例子:
var a=1; function printA(){ console.log(this.a); } var obj={ a:2, foo:printA, bar:function(){ printA(); } } obj.foo(); //2 obj.bar(); //1var foo=obj.foo;foo(); //1
我們定義了一個(gè)全局變量a和一個(gè)打印a的全局變量方法,之后又定義了一個(gè)obj對(duì)象,其中包含a屬性和foo,bar兩個(gè)方法。當(dāng)我們調(diào)用obj.foo()打印了2,調(diào)用obj.bar()打印了1.
分析:
不管printA在哪里定義的,我們this的指向只取決于被誰(shuí)調(diào)用的。在obj.foo(),foo的屬性值為printA,被obj直接調(diào)用,所以this指向obj,this.a就是obj.a=2了;
當(dāng)我們調(diào)用obj.bar()時(shí),bar的屬性值為function(){printA()},沒(méi)有明確哪個(gè)對(duì)象來(lái)調(diào)用printA方法,this默認(rèn)指向全局對(duì)象window,所以this.a=window.a=1;
第三種情況我們把obj.foo值賦予了foo變量,在調(diào)用的時(shí)候就相當(dāng)于是window.foo()了,打印1。
小結(jié):this的指向不是函數(shù)聲明是綁定的,而是在函數(shù)運(yùn)行過(guò)程中動(dòng)態(tài)綁定的。
5.改變this的指向方法:applay call bind
話不多話:寫(xiě)了一個(gè)例子,大家先看,萬(wàn)一比喻不恰當(dāng),大家能理解其中意思即可
var liLei={ name:'liLei', money:10, buyPen:function(){ this.money=this.money-1; console.log(this.name+" have money:"+this.money) } } var hanMeiMei={ name:'hanMeiMei', money:20, buyPan:function(){ this.money=this.money-2; console.log(this.name+" have money:"+this.money) } } liLei.buyPen(); // liLei have money:9 hanMeiMei.buyPan(); //hanMeiMei have money:18
例子很好理解,輸出的結(jié)果相信大家也能看得明白,哪天,韓梅梅想買(mǎi)一個(gè)盆,她買(mǎi)不了,因?yàn)樗€沒(méi)有這個(gè)方法,她一想:我沒(méi)有這個(gè)方法,但是李雷有啊,我打電話給李雷把錢(qián)他讓他幫我買(mǎi)??;后來(lái)李雷想買(mǎi)一個(gè)盤(pán),實(shí)現(xiàn)方法也是如此。那么,在代碼中如何實(shí)現(xiàn)呢?
JavaScript有好幾個(gè)方法可以實(shí)現(xiàn):call,apply,bind。
call方法:
語(yǔ)法:call(thisObj,Object)
定義:調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
說(shuō)明:
call 方法可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法。call 方法可將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對(duì)象。如果沒(méi)有提供 thisObj 參數(shù),那么 Global 對(duì)象被用作 thisObj。
liLei.buyPen.call(hanMeiMei); //hanMeiMei have money:19 hanMeiMei.buyPan.call(liLei); //liLei have money:8
apply方法:
語(yǔ)法:apply(thisObj,[argArray])
定義:應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
說(shuō)明:
如果 argArray 不是一個(gè)有效的數(shù)組或者不是 arguments 對(duì)象,那么將導(dǎo)致一個(gè) TypeError。如果沒(méi)有提供 argArray 和 thisObj 任何一個(gè)參數(shù),那么 Global 對(duì)象將被用作 thisObj, 并且無(wú)法被傳遞任何參數(shù)。
liLei.buyPen.apply(hanMeiMei); //hanMeiMei have money:19 hanMeiMei.buyPan.apply(liLei); //liLei have money:8
bind方法:
liLei.buyPen.bind(hanMeiMei)(); //hanMeiMei have money:19 hanMeiMei.buyPan.apply(liLei)(); //liLei have money:8
小結(jié):三種方法的相同指出是:可以改變this的指向,不同之處是:apply接受的參數(shù)為一個(gè)數(shù)組,call接收的參數(shù)為一個(gè)個(gè)獨(dú)立的值;apply,call會(huì)直接調(diào)用方法,bind改變this的指向返回一個(gè)方法不調(diào)用。
注:有些低版本的瀏覽器不支持函數(shù)使用bind方法,我們?cè)谧鰹g覽器兼容時(shí)可以加以判斷,具體實(shí)現(xiàn)方法暫不贅述。
以上就是個(gè)人對(duì)于this的指向問(wèn)題的理解,我們只需記住一點(diǎn):this指向-誰(shuí)調(diào)用,指向誰(shuí)。不得不說(shuō)JavaScript真是個(gè)奇妙的世界,文中有紕漏不足的地方,歡迎指正。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。