2 回答
TA贡献2021条经验 获得超8个赞
1.每次运行f1
,函数体都会重新执行,所以在第二次运行f1
后,nAdd
函数体中的n
已经变成了新的n
,值为9
2.全局变量是result
和consult
。这句话的f2
和f1
指的是运行上下文,具体到这个问题可以理解为变量n
和f2
TA贡献1847条经验 获得超11个赞
闭包讲清楚不是很容易,我尽量讲得清楚些
1.那为什么consult()这里打印出来的不是10,而是9呢?n值不是被保存下来了吗?
这个问题可以简化下,实际就是下面这个问题:
var result=f1(); // 内存里保存了一个 nvar consult=f1(); // 内存里也保存了一个 n
问题是,但是这两个 n 是同一个么?
如果是同一个,那就是题主的意思; 不是同一个,就是阮老师的意思;
实际上不是同一个,js权威指南上是这么说的
我的理解就是,这个 n 是函数调用的时候才添加到作用域链的,那么两次调用函数赋值给变量,当然声明了两次,添加了两次,而且在不同的作用域链中,如果是同一个 n 在同一个作用域,不就是重复声明了么?你把 var 换成 let 会报错的,为什么说在不同的作用域链中呢?当你声明了 consult 之后,consult的作用域链中全局对象里有 result,result的作用域链中全局对象里有 consult 嘛?明显没有啊,所以两个 n 在不同的作用域链中,当然不是同一个;或者再粗浅理解下,你调用一个函数两次赋值给不同变量,难道函数内的变量都是为两个变量共享,用的是同一个嘛?当然不是啊,,,
2.还有就是“f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中” f2为什么被赋给了一个全局变量?这个变量是谁?
var result=f1(); // f1() 函数执行到 return f2,就把 f2 赋值给了 result,result 是全局变量
var consult=f1(); // f1() 函数执行到 return f2,就把 f2 赋值给了 consult,consult 是全局变量
2.还有就是“f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中” 这句话又是什么意思呢?
var result=f1();//result=f2 不完全等价,但是可以用来参考
因为把 f2 赋值给 result,实际上就是在 result 上保存了对 f2的引用,而 f2 里又保存了对 n 的引用,而 f2 和 n 都存在于 f1 的局部环境里,所以导致了 n,f2,f1 都不会被垃圾回收,也就是说 f2,f1,n 都保存在内存中;(因为 js 的垃圾回收机制存在引用计数的规则,当这个值的引用次数变成 0 时,这个值才会被垃圾回收,释放内存,引用次数不为 0 ,就继续保存在内存中,不会被垃圾回收)
(实际上我觉得 f1 已经不在内存中了,不过这个不影响闭包的理解)
添加回答
举报