理解this指針的用法

this指針的用法

常規用法

對this的理解是,指向 直接操作這個量的函數(或變量、對象)所屬的對象 的指針,也就是指向爹的爹,指向爺爺。通過幾個例子瞭解一下this的常見用法:

var name = 1;
var util = {
    name: 2,
    myName: this.name
    getName: function(){
        return this.name;
    },
    sub: {
        name: 3,
        getName: function(){
            console.log(this);
            return this.name
        }
    }
}

常規的this使用及結果

console.log(util.myName);  //1 this指向window
console.log(util.getName()); // 2 this指向util
console.log(util.sub.getName()); // 3 this指向sub

如果是下列情況

var a = util.getName;
console.log(a()); //結果爲1

解釋:a=util.getName;使得 a 成爲一個全局函數,即

a=function(){return this.name;} 

此時的this指向 window ,得到 window.name
另一種情況:

var b = util.sub;
console.log(b.getName()); // 3 

解釋:同理上個例子, b 是一個全局對象,

b = {
    name: 3,
    getName: function(){
        console.log(this);
        return this.name
    }

b.getName() 中的this即指向getName()所屬的對象 b ,得到 b.name

還有,如果返回值是一個對象,那麼this指向的就是那個返回的對象,如果返回值不是一個對象那麼this還是指向函數的實例。例子如下:

function getName(){  
    this.name = 1;  
    return {}; // 返回對象
}
var a = new getName;  
console.log(a.name); //undefined

function getName(){  
    this.name = 1;  
    return 2; // 返回非對象
}
var d = new getName;  
console.log(d.name); //1

匿名函數中的this

在非嚴格模式下,匿名函數的執行環境具有全局性,因此其this對象指向window.
例子如下:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window(非嚴格模式)或undefined(嚴格模式)
        };
        return fn();
    }
};

要想獲得預期的結果,可以使用以下hack寫法,加一行 var that = this;

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            var that = this;
            return new Date().getFullYear() - that.birth; // that指向obj
        };
        return fn();
    }
};

箭頭函數中的this

箭頭函數和匿名函數的區別:箭頭函數內部的this是詞法作用域,由上下文確定。
回顧前面的例子,由於JavaScript函數對this綁定的錯誤處理,無法得到預期的結果。
現在,箭頭函數完全修復了this的指向,this總是指向詞法作用域,也就是外層調用者obj

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
        return fn();
    }
};
obj.getAge(); // 25

如果使用箭頭函數,以前的那種hack寫法:

var that = this;

就不再需要了。

由於this在箭頭函數中已經按照詞法作用域綁定了,所以,用call()或者apply()調用箭頭函數時,無法對this進行綁定,即傳入的第一個參數被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章