你是個什麼this啊?

在JavaScript中有一個神奇的關鍵字,那就是大名鼎鼎的this,能夠說,掌握了this纔算進入了JavaScript的大

this關鍵字的含義很是明確,就是指代當前的對象,那麼什麼是「當前」就是咱們要重點關注的了。bash

在JavaScript中this的含義要更豐富,它能夠是全局對象、當前對象或者任意對象,這徹底取決於函數的調用方式。JavaScript中函數的調用有如下幾種方式:做爲對象方法調用,做爲函數調用,做爲構造函數調用,和使用apply或call調用。app

做爲函數調用

這是咱們最經常使用的方法,這種調用方式屬於全局調用,這裏的this就成了全局對象。函數

function f(){
    this.n = "hello";
    console.log(this.n);
    console.log(this);
}
f(); // hello    window

複製代碼

調用f時,輸出了"hello"還有window。this

var n = "hello"
    function f(){
        console.log(this.n);
    }
    f();// hello
複製代碼

調用f時,仍然輸出了hello。spa

做爲對象方法調用

var name = "cat";
    var dogs = {
        name:"tom",
        showName:function(){
            console.log(this.name);
        }
    }
    dogs.showName();// 輸出tom
    var otherName = dogs.showName;
    otherName();// 輸出cat
複製代碼

快來看,當執行dogs.showName();時,輸出tom,說明這個時候this是指向dogs這個對象的。而當咱們嘗試把dogs.showName賦給otherName時,咱們很容易想到這個showName()是作什麼用的,顯然輸出它函數的執行環境所指向對象的name,而此時otherName變量至關於window對象的一個屬性,所以otherName()執行的時候至關於window.otherNAme(),即window對象調用otherName這個方法,因此this關鍵字指向window,因此會輸出cat。code

做爲構造函數調用

JavaScript中的構造函數也很特殊,構造函數,其實就是經過這個函數生成一個新對象(object),這時候的this就會指向這個新對象,若是不用new調用,則和普通函數同樣。對象

function f(){
        this.n = "hello";
    }
    var other = new f();
    console.log(other.n);//hello
複製代碼

再來看,咱們爲f函數new(構造)了一個新的對象other,那麼this就會指向這個對象,因此會輸出hello。ip

使用apply或call調用

apply()是函數對象的一個方法,它應用某一對象的一個方法,用另外一個對象替換當前對象。string

var n = "hello";
    function f(){
        console.log(this.n);
    }
    var a = {};
    a.n = "hey";
    a.m = f;
    a.m.apply();//hello
複製代碼

在這段代碼中,當apply()的參數爲空時,就是沒有對象區替換掉當前的對象,因此默認調用全局對象。所以,會輸出hello,證實this指的是全局對象。那麼試試給apply()指定一個對象。it

var n = "hello";
    function f(){
        console.log(this.n);
    }
    var a = {};
    a.n = "hey";
    a.m = f;
    a.m.apply(a);//hey
複製代碼

此時輸出了hey,說明對象替換成功,this指向了a這個對象。