在JavaScript的閉包學習過程當中,發如今閉包中使用this會出現很奇怪的現象,但並無想明白,直到看到了你不知道的JS這本書(不過我更喜歡你不懂JS的譯法)。javascript
關於this的問題也不說了,這隻簡單討論一下this的綁定的幾種方式。其實書中有關於this更細緻的討論,若有興趣,自行閱讀You-Dont-Know-JS之this & Object Prototypes。java
function foo(){ console.log(this.a); } var a = 2; foo();
上述的情形就是this默認綁定的方式,在默認綁定的狀況下this等同於全局對象,在瀏覽器下就是window。在嚴格模式下,this被禁止使用默認綁定。git
function foo(){ "use strict"; console.log(this.a); } var a = 2; foo(); //typeError:this is undefined
var a = 12; function foo(){ console.log(this.a); } var obj1 = { a : 42, foo : foo } var obj2 = { a : 2, foo : foo, obj1 : obj1 } var obj3 = obj1.foo; foo(); //12 默認綁定 obj1.foo(); //42 隱式綁定 obj2.foo(); //2 隱式綁定 obj2.obj1.foo(); //42 隱式綁定 obj3(); // 12 默認綁定
上面的方式是隱式綁定,foo被隱式的綁定到obj1,obj2中,從某種角度來講,obj1和obj2對象中持有foo,而且是經過obj1或obj2調用的。你們發現沒有,最後一種是默認綁定,obj3實質上就是等於foo,也就是第一種調用方式,值得注意。再看個例子:github
var a = 12; function foo(){ console.log(this.a); } var obj1 = { a : 42, foo : foo } function doFoo(fn) { fn(); } doFoo(obj1.foo); //12
function foo(){ console.log(this.a); } var obj1 = { a:42 } foo.call(obj1); //42
當咱們使用call和apply調用函數時,函數中的this會被綁定到call或apply的第一個參數上。此例中foo中this被顯式綁定到obj1上。瀏覽器
function foo(a) { this.a = a; } var bar = new foo(2); console.log(bar.a); // 2
咱們發現this被綁定到bar上去了,這就是new綁定。閉包
默認綁定<隱式綁定<顯式綁定<new綁定。app
若是你們對證實過程感興趣也能夠參考書中的內容。函數