Javascript中的this,是每個FE都需要花費一段時間要去認真理解的的東西。this具體指的是什麼?
this
在javascript語言中,凡是發生函數調用的地方,都會產生this。像在Java中,如果有this,那麼它一定是代表其所在的對象。但是Javascript中函數調用多種多樣,不同的調用方法,this也將會指代不同的東西。我們先來分析一下函數的調用方式,據我使用過的有這麼四種方式:
1 作爲函數調用,函數嘛,肯定是會以函數的方式進行調用的,在這種情況下,this將會指向全局,即window對象
this.x = 0;
function foo(){
console.log(this.x);
}
foo();//0
嵌套的函數調用:
this.x = 0;
function foo(){
console.log(this.x);
function bar(){
console.log(this.x);
}
bar();
}
foo();//0 0
對象下的函數調用:
this.x = 3;
var o = {
x:5,
m:function(){
console.log(this.x);
function foo(){
console.log(this.x);
}
foo();
}
};
o.m();//5 3
無論嵌套多深,函數調用的this都會指向window。
2 作爲對象的成員方法,此時this自然指向這個對象了。
var obj = {
name:'zhangsan',
say:function(){
console.log(this.name);
}
};
obj.say();// zhangsan
function foo(){
console.log(this.name);
}
var obj = {
name:'zhangsan',
say:foo
};
obj.say();//zhangsan
var foo = {
name:'lisi',
say:function(){
console.log(this.name);
}
};
var obj = {
name:'zhangsan',
say:foo.say
};
obj.say();//仍然打印 zhangsan
雖然成員方法有時不是直接寫在對象下面的,但是如果最後還是這個對象調用了這個方法,那麼this仍然指向這個對象。
3 new 出的對象中,this一般指向該對象。這個用法和Java中的類似,在構造函數中使用this,將指向new創建的新對象上。在此就不直接舉例了。
4 call(),apply(),bind()方法,這三個方法,在我的一篇博客中明確的解釋了他們的用法:關於call,apply,bind方法的理解,他們是用來改變函數中的this指向的,這裏也不進行舉例了,不明白的話,可以看一看我那篇文章。
其實,說到頭來,還是對javascript的原理不太瞭解,所以纔對this 不好掌握,我在知乎上看到一篇文章:這裏寫鏈接內容,這裏面就明確寫到了this該怎麼理解。
他寫道,直接函數調用和對象成員方法的調用都是javascript中的語法糖,真正所有的方法的調用都是使用call()來調用的。
fun.call(context,arg1,arg2...);
在這裏的context就是函數運行的上下文,也就是this對象了,
直接函數調用其實可以寫成這樣:
fun();
/*寫成這樣:*/
fun.call(undefined);
obj.fun();
/*寫成這樣:*/
obj.fun.call(obj);
所以,在javascript中,我們自始至終只有一種函數調用方式:那就是:
fun.call(context,arg1,arg2);
從我那篇文章中可以知道,當context爲undefined時,上下文就會指向windows.因此:
this.x = 1;
function foo(){
console.log(this.x);
}
foo();//1
foo.call(undefined);//1
var obj = {
name:'zhangsan',
say:function(){
console.log(this.name);
}
}
obj.say();//1
obj.say.call(obj);//1
有一個例子:
var foo = {
name:'lisi',
say:function(){
console.log(this.name);
}
};
var obj = {
name:'zhangsan',
say:foo.say
};
obj.say();//仍然打印 zhangsan
這裏say:foo.say,我們知道函數也是一個對象,所以,這裏只是一個引用的傳遞,所以這裏obj.say()調用的只是這個方法,跟foo這個對象並沒有任何關聯。
感謝:這裏寫鏈接內容