this
在js中一直是謎同樣的存在着,在面試中也是常常會被問道,接下來總結下我所理解的this
。
首先引入祕密花園中對this的工做原理,文中指出有五種狀況,分別是:javascript
this; //在全局範圍內使用`this`,它將會指向全局對象複製代碼
foo(); //this指向全局對象複製代碼
test.foo(); //this指向test對象複製代碼
new foo(); //函數與new一塊使用即構造函數,this指向新建立的對象複製代碼
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); //this被設置成bar
foo.call(bar, 1, 2, 3); //this被設置成bar複製代碼
有這樣一道題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
的值就是文中的context
,this
就是你函數調用時傳入的context
。瀏覽器
舉例代碼中:app
function foo() {
console.log(this);
}
foo();複製代碼
當你沒法確認this
指代的值時,轉化成call
形式會更好理解ide
function foo() {
console.log(this);
}
foo.call(undefined); //or foo.call();複製代碼
函數執行結果爲window
,在瀏覽器中有一條規定,傳入context
爲null
或undefined
時,則爲全局對象(window對象);嚴格模式下context
爲undefined
。函數
舉例代碼中: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。
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
的理解,若有錯誤請狠拍磚。