總結(jié)一波 this 的理解搞坝,首先在最開(kāi)始引用一句“this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰(shuí)”
1.全局調(diào)用
this 前面如果沒(méi)有明確的出現(xiàn)函數(shù)等調(diào)用形式魁袜,那大多數(shù)時(shí)候我們可以確定是指向全局對(duì)象Global桩撮,舉栗子:
var a=1;
function test() {
var a=2;
console.log("test:",this.a); //test: 1
}
console.log("global:",this.a); //global: 1
test();
2.對(duì)象調(diào)用
對(duì)象調(diào)用一般會(huì)出現(xiàn) test.fn() 或 test[fn],<strong>“.”</strong>或者<strong>“[]”</strong>這樣的關(guān)鍵符號(hào)峰弹,這個(gè)時(shí)候 this 指向的就是那個(gè)直接調(diào)用它的對(duì)象店量,舉栗子:
var test = {
a:10,
fn:function(){
console.log(this.a); //10
}
}
test.fn();
這里的 this 指向的就是對(duì)象 test,因?yàn)檎{(diào)用這個(gè) fn 是直接通過(guò) test.fn() 執(zhí)行的鞠呈,那自然指向就是對(duì)象 test 融师。
但是有沒(méi)有可能出現(xiàn) windown.test.fn() 這樣的調(diào)用方式呢?我們看一下如果這樣調(diào)用會(huì)怎么樣蚁吝?
var test = {
a:10,
fn:function(){
console.log(this.a); //10
}
}
window.test.fn();
答案依然是 10 旱爆,所以我們更加可以確定,在對(duì)象調(diào)用時(shí)灭将,是指向那個(gè)直接調(diào)用它的對(duì)象疼鸟。那么如果,它前一個(gè)調(diào)用它的方法沒(méi)有這個(gè)屬性呢庙曙?
var c=100;
var test = {
a:10,
fn:function(){
console.log(this.a); //undefined
}
};
window.test.c;
所以空镜,不管調(diào)用它的函數(shù)有沒(méi)有這個(gè)屬性,它都會(huì)指向調(diào)用它的函數(shù)不改變捌朴。但是吴攒,這里我們?cè)倏匆幌麻_(kāi)始我們說(shuō)過(guò)的“this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰(shuí)”砂蔽,我們換一個(gè)方式輸出:
var test = {
a:10,
b:{
a:12,
fn:function(){
console.log("this.a:",this.a); //undefined
console.log("this:",this); //window
}
}
}
var put = test.b.fn;
put();
不難理解洼怔,this 永遠(yuǎn)指向的是最后調(diào)用它的對(duì)象,也就是看它執(zhí)行的時(shí)候是誰(shuí)調(diào)用的左驾,雖然函數(shù) fn 是被對(duì)象 b 所引用镣隶,但是在將 fn 賦值給變量j的時(shí)候并沒(méi)有執(zhí)行所以最終指向的是 window,這和上面那個(gè)直接執(zhí)行 fn 不一樣的诡右。
3.構(gòu)造函數(shù)調(diào)用
構(gòu)造函數(shù)調(diào)用安岂,簡(jiǎn)而言之就是 new 會(huì)改變 this 的指向,舉栗子:
function Fn(){
this.put = 2;
}
var a = new Fn();
console.log(a.put); //2
這里通過(guò) new 帆吻,this 指向了新的對(duì)象 a 域那。
4.apply 調(diào)用
與 new 的作用相似的是,apply 也會(huì)改變 this 的指向猜煮,它會(huì)使 this 的指向改為它的第一個(gè)參數(shù)次员,當(dāng)它的參數(shù)為空的時(shí)候败许,默認(rèn)是指向全局,舉栗子:
var x = 0;
function test(){
alert(this.x);
}
var put={};
put.x = 1;
put.m = test;
put.m.apply(); //0
這里淑蔚,apply 后面沒(méi)有加參數(shù)市殷,所以它默認(rèn)指向全局,輸出結(jié)果為 0 證明 <strong>put.x=1</strong> 并沒(méi)有用束倍,但是如果加入?yún)?shù)呢被丧?
var x = 0;
function test(){
alert(this.x);
}
var put={};
put.x = 1;
put.m = test;
put.m.apply(put); //1
這個(gè)時(shí)候, this 指向的就是對(duì)象 put 绪妹。
有個(gè)很奇妙的問(wèn)題甥桂,當(dāng) this 遇到 return 會(huì)怎么樣呢?用代碼說(shuō)話:
function test()
{
this.a = 100;
return {};
}
var put = new test;
console.log(put.a); //undefined
function test()
{
this.a = 100;
return function(){};
}
var put = new test;
console.log(put.a); //undefined
function test()
{
this.a = 100;
return 10;
}
var put = new test;
console.log(put.a); //100
function test()
{
this.a = 100;
return undefined;
}
var put = new test;
console.log(put.a); //100
很奇妙的發(fā)現(xiàn)邮旷,當(dāng) return 返回的是一個(gè)對(duì)象黄选,那么this指向的就是那個(gè)就是那個(gè)對(duì)象,如果不是一個(gè)對(duì)象那么 this 還是指向函數(shù)的實(shí)例婶肩。你以為這樣就完了么办陷?不病游,JS 永遠(yuǎn)會(huì)給你驚喜穆役,看下面這段代碼:
function test()
{
this.a = 100;
return null;
}
var put = new test;
console.log(put.a); //100
雖然我們知道 <strong>typeof(null) ===object</strong> 但是,這里的 null 卻被特殊對(duì)待适肠。