闭包函数, 是独立调用,而不是方法调用。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