前端知識學習----this詳解

關於this,首先要知道this的是在代碼執行的時候才能確定的,定義的時候不能確定,因爲this是執行上下文的一部分,而執行上下文是在代執行的時候才能確定的。實際上this的最終指向的是那個調用它的對象。
想理解this先看幾個例子:

var a = {
    name:'A',
    fn: funcrion(){
        console.log(this.name);   
        console.log(this);
    }
}
a.fn(); //this.name === 'A'; this===a
a.fn.call({name:'B'}); //this.name===='B'; this==={name:'B'}
var fn1 = a.fn;
fn1();  //this.name === undefined; this===window

通過上面的例子可以看出this的執行會有不同,主要集中在以下幾種情況:
1.作爲構造函數執行,在構造函數中(上面例子未體現)
2.作爲對象屬性執行,上述代碼中的a.fn();
3.作爲普通函數執行,上述代碼中fn1();
4.用於call,apply,bind,上述代碼中a.fn.call({name:’B’});

其中fn1() 的執行結果有些出乎意料,上文說過‘實際上this的最終指向的是那個調用它的對象’,fn1中this爲什麼指向了window?繼續來看例子:

function a() {
    var user = "例子";
    console.log(this.user); //undefined
    console.log(this); //window
} 
a();

按照我們上面說的this最終指向的是調用它的對象,這裏的函數a實際是被Window對象所點出來的,下面的代碼就可以證明:

function a() {
    var user = "例子";
    console.log(this.user); //undefined
    console.log(this); //window
} 
window.a();

繼續看例子:

var o = {
    user: "例子",
    fn: function(){
        console.log(this.user); //'例子'
        console.log(this); // o
    }
}
o.fn(); ==>window.o.fn()

o.fn();等價於window.o.fn(),但是this並沒有指向window,而是指向O對象;是不是有些迷惑,繼續看例子:

var o = {
    a = 10;
    b : {
        a:12;
        fn:function(){
            console.log(this.a); //12
            console.log(this); //b
        }
    }
}
o.b.fn();

同樣屬性都是對象o調用出來的,但同樣this沒有指向O。其實我們需要知道以下幾點:

1.如果一個函數中有this,但是沒有被上一級對象調用,那麼this就指向window,嚴格模式下t’his將指向undefined;
2.如果一個函數中有this,這個函數被上一級對象調用,那麼this指向上一級對象;
3.如果函數中有this,這個函數中包含多個對象,儘管這個函數是被最外層的對象所調用,this指向的也是其上一級對象。(上面的例子中,將b對象的值註銷既可以驗證)

var o = {
    a = 10;
    b : {
        //a:12;
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //b
        }
    }
}
o.b.fn();

還有個特殊的例子:

var o = {
    a = 10;
    b : {
        a:12;
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window;
        }
    }
}
var c = o.b.fn;
c();

this指向的是最後調用它的對象,也就是看它執行的時候是誰調用的,這個例子中雖然函數fn是被對象b所引用,但是在將fn賦值給變量c的時候並沒有執行所以最終指向的是window。

在構造函數中this指向也會不同:

function Fn(){
    this.user = '例子';
}
var a = new Fn();
console.log(a.user) //'例子'

這裏a可以調用到user的值,因爲構造函數new關鍵字改變了this的指向,所以將this指向a。

當this遇到return時結果也會有差異,如下面的連個例子:

function Fn(){
    this.user = '例子';
    return {};
}
var a = new Fn();
console.log(a.user) //undefined
function Fn(){
    this.user = '例子';
    return 1;
}
var a = new Fn();
console.log(a.user) //'例子'
總結: 如果返回值是一個對象,那麼this指向返回的這個對象,如果返回值不是一個對象,那麼this還是指向函數的實例;null也是一個對象,但是null比較特殊,返回值是null,this還是指向函數的實例。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章