码迷,mamicode.com
首页 > 其他好文 > 详细

你是不是在不知不觉间创建了闭包呢?

时间:2015-10-18 14:09:01      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

有时候我们会在不知不觉间创建出闭包,给我们打来不必要的麻烦。比如这一个经典的例子:

技术分享
 
我们希望能把0-9这10个数字打印出来,但实际上每个函数都返回10.
 
技术分享
 
对这一段代码的运行结果高程上是这么解释的:
 
“因为每个函数的作用域链都保存着其父函数(在这里就是Nico函数)的活动对象(每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中,在函数作用域中,也把变量对象称为活动对象),所以它们引用的都是同一个变量 i 。当父函数数返回后,变量 i 的值是10,此时每个函数引用的都是同一个变量对象,所以在每个函数内部 i 的值都是10.”
 
通俗点说就是:Nico函数的变量对象只有一个,所以for循环copy出来的10个子函数都只能引用同一个变量对象,而 i 值是被定义在变量对象中的,所以当 i 值更新为10之后,因为引用的同一个变量对象也相当于引用着同一个 i ,所以这10个函数最后都会返回10.
 
但是这样的解释实在有点过于理论了,所以我自己的理解是这样的:

            “因为嵌套函数并没有被立即执行,所以循环10次之后只是保存10
             个这样的函数 function(){ return i; },调用Nico函数把这10个
             函数保存在数组中,在最后循环数组输出的时候再返回 i 值,但是
             那时候for循环已经结束了,i 为10,所以执行结果便是弹出10个10;”
 
改写一下代码证明一下我的思路:
技术分享
 
每循环一次我让匿名函数立即执行并返回一个对应的 i 值存在niconico变量当中,
 
这是执行结果
技术分享
 
结果证明我的理解并没有错,我每一次循环都会立即把对应的 i 值返回出来,因为 i 是一直在变化的,如果等到循环结束才调用的话,到那个时候 i 的值已经是10了,照这种思路其实还可以这样写:我每一次循环并不立即执行返回相应 i 值,但是每一次循环我都把当时的 i 的值储存在对应的函数当中,等循环结束再调用的时候,每一个也都能返回正确的 i 的值。talk is cheap,show you the code:
 
技术分享

 上面代码执行结果也是一样的。
 
 好的这就结束了,纰漏之处还请各路高手们不吝赐教。

你是不是在不知不觉间创建了闭包呢?

标签:

原文地址:http://www.cnblogs.com/tianheila/p/4886653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!