關於this經常有些愛混淆,現就此總結下,便於以後查閱。
主要參考自 1.王福朋的博客:我比較喜歡他寫博客的風格。
http://www.cnblogs.com/wangfupeng1988/p/3988422.html
2.阮一峯大大的博客:
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
this是Javascript語言的一個關鍵字。
它代表函數運行時,自動生成的一個內部對象,只能在函數內部使用。隨着函數使用場合的不同,this的值會發生變化。但是有一個總的原則,那就是this指的是,調用函數的那個對象。——這句話很精髓。
function test1(){
var a = "哈哈";
console.log(this.a); //undefined
console.log(this); //Window
}
test1();
這裏比較好說明,undefined出現的原因,就是this指向的是window對象。他就是在window中被調用。
var testobj = {
name:"jerry",
fn:function(){
console.log(this.name); //jerry
}
}
testobj.fn();
testobj的時候對fn()進行了調用,所以,這時的this是這個testobj對象。
這前面這樣解釋,確實沒什麼問題,且對大部分場合都試用,但在部分情境下,這裏this又不受用了。
我就在調用testobj前面加個window. ,這裏依然沒有影響結果。所以這裏的調用對象又要變通下,不是最終的window,而是testobj這一級對象。就此,我又去查了一番,現部分總結在下面:(不對,請指正!)
情況1:如果this沒有被上一級的對象所調用,那麼this指向的就是window。
情況2:如果this有被上一級的對象所調用,那麼this指向的就是上一級的對象。那就是上個例子的testobj對象。
情況3:如果this所在的函數包含多個對象,儘管這個函數是被最外層的對象所調用,this指向的也只是它上一級的對象。
var testobj = {
a:1,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
testobj.b.fn();
和這個比較:
var testobj = {
a:1,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var f = testobj.b.fn;
f();
這是一個賦值定義,調用函數的問題。這就要弄懂,什麼時候this被誰調用的問題。後面的例子雖然函數fn是被對象b所引用,但是在將fn賦值給變量j的時候並沒有執行所以其指向的是window。前者是直接調用,所以兩者不同,this.a也就不一樣。
還有就是前面兩位大神都講過的,構造函數的this。我們來看看:
function Foo(){
this.content = "構造函數";
console.log(this);//Foo
}
var obj = new Foo();
console.log(obj.content); //"構造函數"
再看看這個,
function Foo(){
this.content = "構造函數";
console.log(this);//window
}
Foo();
console.log(this.content); //"構造函數"
這裏主要就是看其構造函數有沒有new對象出來,有的話,那this指向這個對象,沒有,就作爲普通函數調用,其指向全局window。
王大大也在第四點講到了這一點。其中,這個例子有點難以理解,
var testobj = {
a:1,
fn:function(){
function f(){
console.log(this.a); //undefined
console.log(this); //window
}
f();
}
}
testobj.fn();
開始還是有些許不明白,最後其實溯其本源看的話,f()就作爲普通函數調用,所以還是指向window,那this.a也就取不到值了。
最後一種情況,call()和apply()、bind()會改變this指向。上代碼:
var testobj = {
content:"jerry",
fn:function(){
console.log(this.content); //jerry
}
}
var b = testobj.fn;
b.call(testobj);
也就是說,this就會指向那個對象。apply()和call()類似,只是後面傳的值是數組。
bind()和以上都有所不同,主要是它的返回值不一樣,它返回的是函數。
var testobj = {
content:"jerry",
fn:function(){
console.log(this.content); //jerry
}
}
var f = testobj.fn;
var a = f.bind(testobj);
a(); //執行a()後,纔會打印。
目前就總結出了,這麼多,以後要是還有其他的,我再補充。