閉包函數, 是獨立調用,而不是方法調用。javascript
var a = true; function fun(){ function test(){ console.log(a) } return test; } var o = { a : false; fun : fun; } o.fun()(); // true
因爲閉包的this默認綁定到window對象,但又經常須要訪問嵌套函數的this,因此經常在嵌套函數中使用var that = this,而後在閉包中使用that替代this,使用做用域查找的方法來找到嵌套函數的this值java
var a = true; function fun(){ var that = this; // 用來記錄 fun 的 this function test(){ console.log(that.a) } return test; } var o = { a : false; fun : fun; } o.fun()(); // false
在方法調用時(被對象包含的函數,被對象直接調用時),this隱式的 綁定到該對象上。 ``` var a = 0; function fun(){ console.log(this.a) } var o = { a : 1; fun : fun; } o.fun() // 1 ``` 當對象嵌套時,依然是直接對象 ``` var a = 0; function fun(){ console.log(this.a) } var o1 = { a : 1; fun : fun; o2:{ a : 2; fun : fun; } } // fun函數的直接對象o1 o1.fun() // 1 // fun函數的直接對象是O2 o1.o2.fun() // 2 ```
經過 call() ,bind() ,apply() 方法, 把對象綁定到this上。叫作顯示綁定。 ``` var a = 1; functiont fun(){ console.log(this.a) } var o = { a : 0; } fun() // 1 獨立調用 fun.call(obj); // 0 ``` 在javascript中新增了一些內置函數,具備顯式綁定的功能,例如數組的迭代方法:map()、forEach()、filter()、some()、every() ``` var a = 'windows'; function fun(e){ console.log(e,this.id) } var o = { a : 'o-object'; } [1,2,3].forEach(fun) // 1 'windows' 2 'windows' 3 'windows' // 當咱們指定了綁定對象,this 就會改變 [1,2,3].forEach(fun,obj ) // 1 'o-object' 2 'o-object' 3 'o-object' ```
指的是,隱式綁定的對象有時候會出現綁定對象的丟失,從而默認綁定到windows,主要是賦值操做。
var a = 0; function fun(){ console.log(this.a) } var o = { a : 2; fun : fun; } // 在這裏出現賦值操做,使得o.fun 有了新的別名bar 形成了隱私丟失。 // 由於只是把fun函數賦給了foo,而foo與o對象則毫無關係。 var foo = o.fun;
var a = 0; function fun(){ console.log(this.a); } var o = { a : 1; fun : fun; } // 其實 o.fun 在做爲參數傳遞時候, 也是一個賦值操做。 // 一樣的道理 只是把fun函數賦給了setTimeout 的一個形參 ,而與o對象則毫無關係。 setTimeout(o.fun,100) // 0
function fun(){ console.log( this.a ); } var a = 0; var o1 = {a : 1, fun : fun}; var p2 = {a : 2}; o1.fun() // 1 方法調用 //將o1.fun函數賦值給o2.fun函數,而後當即執行。至關於僅僅是fun函數的當即執行 (o2.fun = o1.fun)();//0 // 注意上下兩種的區別 o2.fun = o1.fun; o2.fun() // 2
其實 在 javascript 內存角度上 O 和 o.fun 是存儲在不一樣的地址上的。 只有o.fun() 纔算是 從o 對象上去調用fun。不然,默認的是直接調用方法。所以綁定到了windows上。windows
(o2.fun = o1.fun)();//0 (false || 01.fun)();//0 (1, o1.fun)();//0
實現一個改變不了的this的綁定
利用顯示綁定手段,能夠是this不能被修改。就是將函數的調用封裝起來 ,顯示的綁定this對象。數組
var a = 0; function fun(){ console.log(this.a) } var o = { a : 2; } var foo = function(){ fun.call(o) // 封裝調用,顯示綁定this對象 } foo() // 0 setTimeout(foo,100);//2 foo.call(window);//2