- 为什么下方代码fn2执行的过程中没有访问foo的变量,依然形成了闭包?
-
代码:
function foo() { var a = 10; function fn1() { return a; } function fn2() { return 10; } fn2(); } foo();
- chrome截图信息
代码:
function foo() {
var a = 10;
function fn1() {
return a;
}
function fn2() {
return 10;
}
fn2();
}
foo();
13 回答12.8k 阅读
7 回答1.9k 阅读
3 回答1.1k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
6 回答889 阅读✓ 已解决
6 回答1.1k 阅读
2 回答1.3k 阅读✓ 已解决
这个要理解
闭包
到底是什么很多地方都讲闭包就是内部函数访问外部函数变量便形成了闭包,这种说法没有问题,这样确实是形成了闭包,但是这种说法很容易造成误解,这只是闭包的形式。
我觉得,要理解
闭包
,就要理解其形成的根本原因——作用域
,个人认为,闭包就是函数作用域
的利用。看你的代码:
这个代码内部形成了三个作用域:
Foo
Fn1
Fn2
作用域是有链式关系的,当函数创建的时候,保存了一个
作用域链
。因此三个作用域可以表示为:
Foo
->Global
Fn1
->Foo
Fn2
->Foo
所以,无论
fn1
和fn2
是否访问外部函数foo
,foo作用域Foo
对fn1
和fn2
是可见的,自然也就形成了闭包
。fn1
利用了闭包,而fn2
没有利用闭包,但不影响闭包的形成无论你用或不用,闭包就在那里无论你用或不用(闭包特性),闭包(一旦形成)就在那里经题主提醒,调试之后发现:
这样的代码,Chrome下作用域链与上文提出的有些差别():
Foo
->Global
Fn1
->Global
Fn2
->Global
而同样的代码,FireFox给出的内容要多一点,但也能进一步看出引擎是有优化能力的:
Foo
->Global
Fn1
-> Foo(optimized away) ->Global
Fn2
-> Foo(optimized away) ->Global
可以看到
optimized away
这样的描述,也就是说,引擎实际上是将其优化掉的因此
内部函数访问外部函数变量
应该是一种条件,如果这个内部函数没有访问过外部函数中的变量,其作用域链中并没有外部函数的作用域。(也许是引擎的一种优化,个人猜测)具体细节,还要进一步去了解