深刻淺出this的理解

this在js中一直是謎同樣的存在着,在面試中也是常常會被問道,接下來總結下我所理解的this
首先引入祕密花園中對this的工做原理,文中指出有五種狀況,分別是:javascript

  • 全局範圍內
this;    //在全局範圍內使用`this`,它將會指向全局對象複製代碼
  • 函數調用
foo();    //this指向全局對象複製代碼
  • 方法調用
test.foo();    //this指向test對象複製代碼
  • 調用構造函數
new foo();    //函數與new一塊使用即構造函數,this指向新建立的對象複製代碼
  • 顯式的設置this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]);    //this被設置成bar
foo.call(bar, 1, 2, 3);    //this被設置成bar複製代碼

從函數調用理解this

有這樣一道題java

var obj = {
    func: function(){
        console.log(this);
    }
}

var foo = obj.func;
obj.func() //this是obj
foo() //this是window複製代碼

解釋函數結果爲何不同?git

這道題能夠從函數調用來理解,從我看到的博文中有這樣的解釋,祕密花園中的函數調用,方法調用,顯式的設置this都屬於函數調用,至關於函數調用的三種方式,能夠寫成github

foo(params);
obj.child.foo(params);
foo.call(context, params); //apply同理複製代碼

並且前兩種均可以寫成第三種形式面試

foo(params); =>> foo.call(undefined, params);

obj.child.foo(); =>> obj.child.foo.call(obj.child, params);複製代碼

因此說函數調用都是foo.call(context, params)的變體,即函數調用只有一種。這樣this的值就是文中的contextthis就是你函數調用時傳入的context瀏覽器

舉例代碼中:app

function foo() {
    console.log(this);
}

foo();複製代碼

當你沒法確認this指代的值時,轉化成call形式會更好理解ide

function foo() {
    console.log(this);
}

foo.call(undefined); //or foo.call();複製代碼

函數執行結果爲window,在瀏覽器中有一條規定,傳入contextnullundefined時,則爲全局對象(window對象);嚴格模式下contextundefined函數

舉例代碼中:ui

var obj = {
    func: function foo() {
        console.log(this);
    }
}

obj.foo();複製代碼

轉化爲call形式爲

var obj = {
    func: function foo() {
        console.log(this);
    }
}

obj.foo.call(obj);複製代碼

很明顯,this指代obj。

Event Handler 中的this

btn.addEventListener('click' ,function handler(){
  console.log(this) // 請問這裏的 this 是什麼
})複製代碼

handler 中的this是什麼?用上面的方法好像無法轉化了,由於不知道addEventListener內源碼實現,查看文檔MDN

一般來講this的值是觸發事件的元素的引用,這種特性在多個類似的元素使用同一個通用事件監聽器時很是讓人滿意。

當使用 addEventListener() 爲一個元素註冊事件的時候,句柄裏的 this 值是該元素的引用。其與傳遞給句柄的 event 參數的 currentTarget 屬性的值同樣。

因此能夠假設瀏覽器addEventListener是這樣實現的

// 當事件被觸發時
handler.call(event.currentTarget, event) // this => event.currentTarget複製代碼

以上就是對this的理解,若有錯誤請狠拍磚。

相關文章
相關標籤/搜索