闭包和this
function create(){ var result =new Array(); for(var i=0;i<10;i++){ result[i]=function(){ return i; } } return result; }
网上很多讲解,但是看完以后总是似懂非懂,今天又看了一遍高程,说说自己的看法。
最后输出数组会得到
result=[10,10,10,10,10,10,10,10,10,10];
与想得到的结果
result=[0,1,2,3,4,5,6,7,8,9]
相差甚远,说一下原因:
create函数内部的闭包可以通过作用域访问到外部函数create中的变量i,当函数create执行完以后i最后的值是10。
而当console.log(result)数组的时候 本质上是打印
result=[function(){return i;},function(){return i;},.....function(){return i;}]
数组中十个匿名函数的结果,因为是引用类型,只能访问到create执行以后i的值。因此是10;
解决方法还是很多的
书上的方法
function create(){ var result =new Array(); for(var i=0;i<10;i++){ result[i]=function(mun){ return function(){ return mun; } }(i); } return result; }
可以返回预期值,然后我又尝试了一下
function xh(){ let sz=[]; for(var i=0;i<10;i++){ sz[i]=function(i){ return i; }(i); } return sz; }
本质上的区别还是数组中保存了匿名函数\数值;
稍经尝试就可以得出结果。
当然少不了let 声明变量i的方法。
关于this对象
有关于this的讲解,追梦子大大讲的很详细,这里贴出链接:彻底理解js中this的指向,不必硬背。
这里说一下高程中的例子
var name='window'; let obj={ name:'obj', get:function(){ return function (){ return this.name; } } }; alert(obj.get()());//window
然后贴出书中的讲解:
前面曾经提到过,每个函数在被调用的视乎都会自动取得两个特殊变量:this 和 arguments。内部函数在搜索着两个变量时,智慧搜索 到其活动对象位置,因此永远不可能直接访问外部函数中的这两个变量。
上面这句话我仍然没读懂。
说一下自己的理解:
alert(obj.get()());
弹出obj.get()
alert(obj.get());
会得到
function (){ return this.name; }
因此alert(obj.get()());只不过是匿名函数在全局里的执行,会返回window的name属性。
来验证自己的想法,将函数进行修改
var name='window'; let obj={ name:'obj', get:function(){ return function (){ return obj.name; } } }; alert(obj.get()());//obj
可以访问到obj里的name属性,由此可以看出上边得到的结论是正确且符合逻辑。在匿名函数的作用域中window的name属性相对于obj的name属性更近一些。
如果能帮到你,不胜荣幸。