理解JavaScript中的this

1、結論在前

javascript中的this是一個老生常談的話題,但不知道是以前那些做者沒講清楚仍是我太笨沒能理解,始終沒能真正理解它,隨着本身在項目過程當中的大量實踐,終於對this比較理解,這裏做個總結,也與你們分享一下。javascript

別的文章一來就舉例子,我這裏首先告訴你們一個結論:java

this指向的是調用函數的那個對象。app

要是以爲理解了就能夠不用看後面的文章了:)函數

2、經典栗子

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        return this.name
    }
};
alert(object.getName());

這是一個全部講this都會使用的簡單而又經典的例子,咱們根據一開始的結論----this指向的是調用函數的那個對象,很容易就知道輸出結果是My Object,接下來咱們將這個經典例子升級。this

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        return function () {
            return this.name
        }

    }
};
alert(object.getName()());

請告訴我輸出結果是什麼。code

許多人會說仍是My Object,那麼你就進入陷阱了。其實這也是JS新手常有的誤區,他們總簡單地覺得this指向this所在的對象,這是錯誤的!必定要牢記結論this指向的是調用函數的那個對象,這個重要的結論我終於說滿三遍。那麼咱們再來分析上面的代碼:對象

首先咱們建立了一個全局變量name,爲它賦值"The Window";接下來咱們建立了對象object,它有個屬性name,屬性值"My Object",這個對象還包含一個方法getName(),而這個方法會返回一個匿名函數,而匿名函數又返回this.nameip

邏輯理清後,我來告訴你們陷阱在哪:開發

匿名函數執行具備全局性,其this對象一般會指向windowget

說"一般"就是說有例外,在經過call()apply()改變函數執行環境的狀況下,this就會指向其餘對象了,這些函數我以後會講到,這裏不作展開。

ok,咱們知道了這個陷阱,但這也只是個沒用的知識點,有用的是怎麼解決這種尷尬的狀況。雖然我以前說不少新手會犯總簡單地覺得this指向this所在的對象這樣的錯誤,可是咱們在實際開發中就是想讓this有這樣的效果,那麼咱們該怎麼作呢?

3、this的綁定

1.var _this=this

這是最基礎的綁定this的方式,將this賦值給一個變量,這個變量能夠取任何名字,我喜歡取名_this,有些人喜歡取名that,咱們再回顧以前升級的例子:

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        var _this=this
        return function () {
            return _this.name
        }

    }
};
alert(object.getName()());

2.bind()

稍微高級點的方法是使用bind()函數,這是一個ECMAScript 5.1出來的擴展方法,與call()apply()是"同期生",他們的關係和差異以後我會專門談。這裏依然是以前的例子:

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        return function () {
            return this.name
        }.bind(this)
    }
};
alert(object.getName()());

3.ES6中的()=>

()=>俗稱箭頭函數,使用它來定義匿名函數,一樣能夠解決this的綁定問題

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        return ()=> {
            return this.name
        }
    }
};
alert(object.getName()());

這是因爲()=>函數體內的this就是定義時所在的對象,而不是執行時所在的對象。

以上,想到再補充吧...

相關文章
相關標籤/搜索