this全面理解
調用位置
調用位置是函數在代碼中調用的位置(而不是聲明的位置).
調用棧(為了到達當前執行位置所調用的所有函數),
調用位置就是當前正在執行的函數的前一個調用中;
調用位置如何決定this的綁定對象
綁定規則
1. 默認綁定
不帶任何修飾的函數引用進行調用
獨立函數調用,可以把這條規則看成無法應用其他規則時的默認規則。
當調用foo的時候,this.a被解析成了全局變量a。this指向全局對象。
如果使用嚴格模式(strict mode),那么全局對象無法使用默認綁定,this會綁定undifined
function foo() {'use strict'console.log(this.a) // Cannot read property 'a' of undefined } var a = 2; // 全局屬性 foo(); // 調用位置,在全局作用域2. 隱式綁定
調用位置是否有上下文對象,或者說是否被某個對象擁有或包含。
function foo() {console.log(this.a); } let obj = {a: 2,foo } obj.foo(); // 2首先聲明foo函數,然后被當作引用屬性添加到obj中。但是無論時直接obj中定義還是先定義再添加為引用屬性,這個函數嚴格來說都不屬于obj對象。
然而,調用位置會使用上下文來引用函數,因此可以說函數被調用時obj對象擁有或包含了它。
當函數引用有上下文對象時,隱式綁定規則會把函數調用中的this綁定到這個上下文對象。
調用foo()時,this被綁定到obj對象。
隱式丟失
會隱式綁定的函數會丟失綁定對象,從而應用默認綁定。
雖然bar是obj.foo的一個引用,但實際上,他引用的是foo函數本身,此時的bar是一個不帶任何修飾的函數調用,應用了默認綁定。
3.顯示綁定
call()、apply(), bind()
4. new綁定
使用new來調用Parent函數,我們會構造一個新對象并把它綁定到parent
()函數調用中的this上。
5.箭頭函數
箭頭函數不適用上述4種規則,他是根據外層作用域來決定。
優先級
new > call/apply/bind>隱式綁定>默認綁定
被忽略的this
常見做法:
(1)apply(null, [])來展開數組,并當作參數傳入函數。
(2)bind(null, 2) 柯里化
function foo(a, b) {console.log(a, b); } var bar = foo.bind(null, 2); bar(3);(3) Object.create(null)
Object.create(null)不會創建Object.prototype這個委托,所以比{}更空。
------------參考《你不知道的JavaScript上》
總結
- 上一篇: new调用函数,new具体做了什么?
- 下一篇: Promises/A+规范中文翻译