this的那些事兒

關於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()後,纔會打印。

目前就總結出了,這麼多,以後要是還有其他的,我再補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章