JS中的this對象詳解

    JS中this關鍵字很常見,可是它彷佛變幻莫測,讓人抓狂。這篇文章就來揭示其中的奧祕。html

     藉助阮一峯老師的話:它表明函數運行時,自動生成的一個內部對象,只能在函數內部使用。這句話看似日常,但是要很是注意三個字:「運行時」,這說明this關鍵字只與函數的執行環境有關,而與聲明環境沒有關係。也就是這個this到底表明的是什麼對象要等到函數運行時才知道,有點相似函數定義時的參數列表只在函數調用時才傳入真正的對象。理解了這一點對後面this關鍵字規律的掌握有很大幫助。數組

     this關鍵字雖然會根據環境變化,可是它始終表明的是調用當前函數的那個對象。這就引出了JS中函數調用的問題。在JS中調用函數的模式能夠分爲4種: 方法調用模式、函數調用模式、構造器調用模式、apply調用模式。這些模式在如何初始化關鍵參數this上存在差別。瀏覽器

1、方法調用模式

     當函數被保存爲一個對象的屬性時,它就可稱爲這個對象的方法。當一個方法被調用時,this被綁定到這個對象上。若是調用表達式包含一個提取屬性的動做(. 或 []),那麼它被稱爲方法調用。例如:app

var name = "window";
var obj = {
    name: "kxy",
    sayName: function() {
        console.log(this.name);
    }
};
obj.sayName();  //kxy

     sayName函數做爲對象obj的方法調用,因此函數體中的this就表明obj對象。函數

2、函數調用模式

當一個函數並不是一個對象的屬性時,那麼它就是被當作函數來調用的。在此種模式下,this被綁定爲全局對象,在瀏覽器環境下就是window對象。例如:this

var name = "window";
function sayName() {
    console.log(this.name);
}
sayName();

     sayName以函數調用模式調用,因此函數體中的this表明window對象。prototype

3、構造函數模式

     若是在一個函數前面加上new關鍵字來調用,那麼就會建立一個鏈接到該函數的prototype成員的新對象,同時,this會被綁定到這個新對象上。這種狀況下,這個函數就能夠成爲此對象的構造函數。例如:htm

function Obj() {
    this.name = "kxy";
}
var person = new Obj();
console.log(person.name);   //kxy

Obj做爲構造函數被調用,函數體內的this被綁定爲新建立的對象person。對象

4、apply調用模式

    在JS中,函數也是對象,全部函數對象都有兩個方法:apply和call,這兩個方法可讓咱們構建一個參數數組傳遞給調用函數,也容許咱們改變this的值。例如:ip

var name = "window";
var person = {
    name: "kxy"
};
function sayName() {
    console.log(this.name);
}
sayName();    //window
sayName.apply(person);   //kxy
sayName.apply();    //window

    當以函數調用模式調用sayName時,this表明window;當用apply模式調用sayName,並給它傳入的第一個參數爲person時,this被綁定到person對象上。若是不給apply傳入任何參數,則this表明window。

     自此,函數調用的4種模式就都介紹完了,this的綁定規律也就是以上幾種,萬變不離其宗。爲了簡單明瞭的介紹4種模式,以上的例子都比較簡單,那麼下面就跟我一塊兒作一個稍複雜的練習,檢驗下本身是否真正掌握了this綁定對象的方法吧!

var name = "window";
function showName() {
    console.log(this.name);
}
var person1 = {
    name: "kxy",
    sayName: showName
}
var person2 = {
    name: "Jake",
    sayName: function() {
        var fun = person1.sayName;
        fun();
    }
}
person1.sayName();    //kxy
person2.sayName();    //window

    首先心中時刻提醒本身this是在函數執行時被綁定的,不要被任何賦值語句打亂陣腳。

    先看第一個執行語句:person1.sayName(); 首先肯定這是方法調用模式,對象爲person1,再看sayName被賦值爲全局函數對象showName,在showName執行時,this綁定的是person1,因此結果爲」kxy」。

    再看第二個執行語句:person2.sayName(); 這仍是方法調用模式,對象爲person2,調用的是它的sayName方法。再看sayName函數體,發現函數體最終執行的函數是fun,fun是用函數調用模式調用的。而fun最終也被賦值爲showName函數,由於fun是用函數調用模式調用的,因此這裏的this綁定爲window,結果爲」window「。

    怎麼樣,你作對了嗎?

相關文章
相關標籤/搜索