大家好鹃答,我是IT修真院上海分院第1期的Web學(xué)員劉洪利榆俺,今天給大家分享一下Js中this的指向
1.背景介紹
JAVASCRIPT中THIS指的是什么敬察?
this是JavaScript語言中定義的眾多關(guān)鍵字之一舒萎,它的特殊在于它自動定義于每一個函數(shù)域內(nèi)藐鹤,在函數(shù)運行時致燥,this會自動生成一個內(nèi)部對象登疗,這個對象只能在函數(shù)內(nèi)部使用。同時嫌蚤,隨著函數(shù)使用場合的不同辐益,this的值會發(fā)生變化。但是有一個總的原則脱吱,那就是this指的是智政,調(diào)用函數(shù)的那個對象。
那什么THIS的指向又是什么呢箱蝠?
在JavaScript中续捂,this是動態(tài)綁定的,它可以是全局對象宦搬、當(dāng)前對象或者任意對象疾忍,這完全取決于函數(shù)的調(diào)用方式。這就導(dǎo)致了this具備了多重含義床三,可以使得JavaScript更靈活的使用一罩。但是,帶來了靈活性的同時也會給我們初學(xué)者帶來不少困惑撇簿。
2.知識剖析??
var name = '小明';
function look() {??? ?
????????var name = '二明';???
? ? ? ? console.log(this.name);?? ?
????????console.log(this);?
};?
look(); //小明
總結(jié):在全局作用域中它的 this 執(zhí)行當(dāng)前的全局對象(瀏覽器端是 Window)聂渊,所以才會在全局環(huán)境下查找'name',然后打印出來
var name = '小明';
var name2 = {??? ?
????????name: '二明',??? ?
????????age: 20,???
?????????look: function(){??? ???
????????console.log(this.name);??? ??? ?
????????console.log(this.age);??? ?
????????}?
}?
name2.look();
這里的打印的結(jié)果是打印的第一個是二明四瘫,第二個是20汉嗽。因為調(diào)用look函數(shù)的是name2這個對象,所以this指向的是name2中的name屬性的指向只在函數(shù)中定義的話是確定不了的找蜜,只有當(dāng)被函數(shù)執(zhí)行的時候才能確定this到底指向誰饼暑,也就是誰調(diào)用了這個函數(shù)。
var name ='小明';
var name2 = {
????????name:'二明',
????????func:{
????????????????name:'三明',
????????????????look:function(){
????????????????????console.log(this.name);
????????????????}
????????}
}
name2.func.look();
這里的話洗做,第一個是函數(shù)被name2調(diào)用的弓叛,本應(yīng)打印的是二明,但是最后的打印結(jié)果卻是三明诚纸,是為什么呢撰筷。我們可以看下下面的圖
THIS的指向的三種情況
1.如果一個函數(shù)有this,但是它沒有被上一級對象所調(diào)用畦徘,那么它指向的就是window毕籽。在嚴(yán)格模式下指向的是undefined抬闯。
2.如果一個函數(shù)中有this,這個函數(shù)有被上一級所調(diào)用关筒,那么它指向的就是調(diào)用它的對象溶握。
3.如果一個函數(shù)中有this,且這個函數(shù)外層被多個對象包含蒸播,盡管最終這個函數(shù)是被最外層的對象所調(diào)用奈虾,this指向的也只是函數(shù)上一級的對象。
var name ='小明';
var name2 = {
????????name:'二明',
????????func:{
????????????????look:function(){
????????????????????????console.log(this.name);
????????????????}
????????}
}
name2.func.look();//undefined
雖然函數(shù)look()最終是被func調(diào)用廉赔,哪怕func中沒有name這個屬性,this指向的依然是func匾鸥,所以打印的結(jié)果為undefined蜡塌。但是還有一種特殊情況:
var name ='小明';
var name2 = {
????????name:'二明',
????????func:{
????????????????name:'三明',
????????????????look:function(){
????????????????????????console.log(this.name);
????????????????}
????????}
}
var a = name2.func.look;
a();
這里的話this最終打印的是小明,卻不是我們想象中的三明勿负,這是因為我們重新聲明變量a馏艾,并把look函數(shù)賦值給它,最后執(zhí)行函數(shù)a()的時候奴愉,調(diào)用a()是Window對象琅摩。那句話:誰調(diào)用this,this就指向誰.
3锭硼、常見問題
現(xiàn)象:下面的代碼兩次打印的this不一樣
var obj = {??? ?
????????name: 'qiutc',??? ?
????????foo: function() {??? ??? ?
????????????????console.log(this);??? ?
????????},??? ?
????????foo2: function() {?? ??? ?
????????????????console.log(this);??? ??? ?
????????????????setTimeout(this.foo, 1000);??? ?
????????}?
}?
obj.foo2();
4房资、解決方案
我們可以這么解決:利用 閉包 的特性來處理
var obj = {
????????name:'qiutc',
????????foo: function() {
????????????????console.log(this);
????????},
????????foo2: function() {
????????????????console.log(this);
????????????????var _this= this;
????????????????setTimeout(function() {
????????????????????????console.log(this);// Window
????????????????????????console.log(_this);// Object {name: "qiutc"}
????????????????},1000);
????????}
}
obj.foo2();
可以看到直接用 this 仍然是 Window;因為 foo2 中的 this 是指向 obj檀头,我們可以先用一個變量 _this 來儲存轰异,然后在回調(diào)函數(shù)中使用 _this,就可以指向當(dāng)前的這個對象了
執(zhí)行這段代碼我們會發(fā)現(xiàn)兩次打印出來的 this 是不一樣的:
第一次是 foo2 中直接打印 this暑始,這里指向 obj 這個對象搭独,我們毋庸置疑;
但是在 setTimeout 中執(zhí)行的 this.foo 廊镜,卻指向了全局對象牙肝,這里不是把它當(dāng)作函數(shù)的方法使用嗎?這一點經(jīng)常讓很多初學(xué)者疑惑嗤朴;
其實配椭,setTimeout 也只是一個函數(shù)而已,函數(shù)必然有可能需要參數(shù)雹姊,我們把 this.foo 當(dāng)作一個參數(shù)傳給 setTimeout 這個函數(shù)颂郎,就像它需要一個 fun 參數(shù),在傳入?yún)?shù)的時候容为,其實做了個這樣的?? ??? ?操作 fun = this.foo乓序,看到?jīng)]有寺酪,這里我們直接把 fun 指向 this.foo 的引用;執(zhí)行的時候其實是執(zhí)行了 fun() 所以已經(jīng)和 obj 無關(guān)了替劈,它是被當(dāng)作普通函數(shù)直接調(diào)用的寄雀,因此 this 指向全局對象。
這個問題是很多異步回調(diào)函數(shù)中普遍會碰到的
6.擴展思考
問題:當(dāng)this遇到return時會發(fā)生什么陨献?
答:如果返回值是一個對象盒犹,那么this指向的就是那個返回的對象,如果返回值不是一個對象那么this還是指向函數(shù)的實例
7.參考文獻
參考一:徹底理解JS中this的指向
參考二:阮一峰的博客
????????????????????????????????鳴謝
????????????????????????感謝大家觀看
? ? ? ? ? ? ? ? ? ? ? ? ? BY: 劉洪利?
? ? ? ? ? ? ? ? ? ? ? 參考ppt: 孫劍立
如果這篇文章對你有幫助眨业,并且使你對修真院免費在線學(xué)習(xí)感興趣急膀,可以通過以下鏈接注冊成員
IT修真院上海Web第1期學(xué)員劉洪利: 邀請碼14898047