javascript
学JS的心路历程 -函式(三)this
this是什么,取決于被呼叫的呼叫地點(diǎn)。
?
昨天有提到說(shuō),呼叫函式時(shí)候會(huì)傳遞隱含參數(shù):arguments和this并講解了arguments,今天我們就來(lái)探討this吧!
?
什么是this
我們都會(huì)呼叫函式來(lái)使用,但有想過(guò)到底是從哪里呼叫到這個(gè)函式嗎?
this通常被稱(chēng)作函式背景空間(function context),也就是說(shuō)透過(guò)this我們可以知道到底是由誰(shuí)呼叫這支函式(yjssqsdg)。我們無(wú)法在一開(kāi)始定義它,只有函式呼叫時(shí)候才能確定。
?
函式的呼叫有四種方式:
?
作為函式呼叫
作為一個(gè)(物件)的方法呼叫
作為一個(gè)建構(gòu)式函式呼叫
透過(guò)apply、call呼叫
apply、call我們會(huì)在下一篇中介紹,我們今天主要介紹上述三種呼叫方式。
?
作為函式呼叫
function funA(){
console.log(this);
}
funA();//Window
由于是在全局環(huán)境呼叫funA,所以這時(shí)候的this就會(huì)是window。
?
所以很多剛學(xué)習(xí)的人都會(huì)遇到這個(gè)問(wèn)題:
?
function funA(){
this.count ++;
}
funA.count = 0;
funA();
console.log(funA.count);//0
明明已經(jīng)聲明funA.count = 0怎么會(huì)沒(méi)有加到呢?這就是因?yàn)閒unA是被全局環(huán)境也就是window呼叫,所以this并不是你預(yù)期的funA。
?
那到底加了誰(shuí)的count呢?你可以嘗試印出window.count會(huì)發(fā)現(xiàn)是NaN,是因?yàn)槟阗x予window一個(gè)count屬性且一開(kāi)始沒(méi)有給定初始值,
所以會(huì)變成undefined+ 1 = NaN。
?
或許你認(rèn)為這樣就可以解決問(wèn)題:
?
function funA(val){
val.count ++;
}
var dart = {
count:0
};
funA(dart);
console.log(dart.count);//1
但這樣你只是在逃避this這個(gè)問(wèn)題而已!!
要透過(guò)this解決方案有兩種,一個(gè)是等下提到的作為物件的方法;一個(gè)是明天會(huì)說(shuō)的call及apply。
?
作為方法呼叫
函式可以透過(guò)寫(xiě)在物件里面去呼叫,這個(gè)呼叫方式稱(chēng)作作為方法(method),相信大家都知道,但你知道在這時(shí)候的this是什么嗎?
?
var obj = {
funA:function(){
console.log(this);
console.log(this===obj);
}
}
obj.funA();
//{funA:?}
//true
可以看到這時(shí)候的this是obj物件,也是是說(shuō)我們是透過(guò)obj去呼叫的。
但是要注意一個(gè)小地方:
?
function funA(){
console.log(this);
console.log(this===obj);
}
var obj = {
a:funA
}
funA();
//Window
//false
雖然你認(rèn)為我已經(jīng)讓obj參照f(shuō)unA了,但是當(dāng)你直接執(zhí)行funA時(shí),還是由全局環(huán)境去呼叫,這也呼應(yīng)了我們開(kāi)頭所說(shuō)的「我們無(wú)法在一開(kāi)始定義它,只有函式呼叫時(shí)候才能確定」。
?
我們可以利用作為方法呼叫來(lái)解決作為函式呼叫的問(wèn)題:
?
function funA(){
this.count ++;
}
var obj = {
count:0,
sum:funA
};
obj.sum();
console.log(obj.count);//1
作為建構(gòu)式呼叫
建構(gòu)式的函式聲明就跟任何函式一樣,也可以用聲明和表達(dá)來(lái)建立新物件。
要作為建構(gòu)式函式來(lái)呼叫函式,必須要在函式呼叫前加上new:
?
function myConstructor(){
this.count = 0;
this.sum = function(){
return this.count ++
}
}
var a = new myConstructor();
a.sum();
console.log(a.count);
也許有人會(huì)覺(jué)得,這跟作為方法呼叫很像,那用物件去寫(xiě)就好何必這么麻煩還要學(xué)建構(gòu)式,用奇怪的new去呼叫函式。
?
這邊就來(lái)說(shuō)明一下,使用new呼叫函式時(shí),會(huì)發(fā)生什么事:
?
建立一個(gè)新物件。
此物件被當(dāng)成this參數(shù)傳遞給建構(gòu)式,因此成為建構(gòu)式的函式背景空間(swrebar)。
回傳新建立的物件。
如果我們今天需要兩個(gè)相同的物件,如果用作為物件方法呼叫的話(huà)就必須建立兩個(gè)不同的物件,否則會(huì)參照到同樣的物件并修改。
但是建構(gòu)式就不需要,因?yàn)槊恳粋€(gè)都是一個(gè)新的物件:
?
function myConstructor(){
this.count = 0;
this.sum = function(){
return this.count ++
}
}
var a = new myConstructor();
var b = new myConstructor();
a.sum();
console.log(b.count);//0
以上就是this的基本三種呼叫方式,若有錯(cuò)誤及參考資料未附上勞請(qǐng)留言。
明天我們會(huì)介紹this的稍微進(jìn)階應(yīng)用call及apply。
?
參考資料:
忍者JavaScript開(kāi)發(fā)技巧探秘
你所不知道的JS - this
徹底理解js中this的指向,不必硬背。
轉(zhuǎn)載于:https://www.cnblogs.com/lannyQ-Q/p/9935901.html
總結(jié)
以上是生活随笔為你收集整理的学JS的心路历程 -函式(三)this的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ubantu使用笔记
- 下一篇: 苏宁大促高并发要求下的售后服务运营能力承