function a() {
var propa = 'a'
(function b() {
var propb = 'b'
})()
}
a()
像这样一段代码,在函数 b 没有引用函数 a 里的变量的情况下,函数 b 的作用域链上是否还会包含 函数 a 的作用域?
(function a() {
var propa = 'a'
(function b() {
var propb = 'b'
return function () {
var propc = propa
}
})()
})()
这样,函数 b 内返回了一个闭包出去,这个闭包的作用域链会包含函数 a 的作用域,那么会包含函数函数 b 的作用域吗?
评论里有人说代码会报错。
我在console上试了一下,确实,语句结尾加分号吧(写代码好习惯);
既然有疑问 ,那就写代码验证一下呗。
无论是否使用上一层函数中的变量,都会包含上级的作用域。。。
只不过,在没有访问的时候浏览器可以把不必要的变量甚至作用域优化掉
函数 b 中虽然没有引用函数 a 的任何变量,但是他的确有能力访问到函数a的任何变量,为什么不能说函数 b 的作用域链上是否还会包含 函数 a 的作用域呢?
第二段代码一样道理。
我来以规范的角度回答这个问题,从规范来解释这个问题是最权威、最正确的。
我们都知道,(规范上)函数运行时,会有一个
执行环境
对象push到执行栈顶部,这个执行环境
包括词法环境
,可以把词法环境
理解为执行环境
的一个属性。下面,我们来看,什么是
词法环境
,根据规范:环境记录项:是一个对象,在函数中
你声明的propa/propb/propc和未声明的arguments
等变量都是这个对象的属性外部词法环境引用: 作用域链就是由它链起来的。
由规范可看出
第一个回答:会。因为规范没说不会。
第二个回答:会。因为规范没说不会。
关于闭包变量回收: 其实,现在的js引擎是特别特别聪明的
V8/SpiderMonkey/IE9+用的查克拉
等引擎会把没有用到,将来也不可能用到的变量回收掉了,而早期Opera/IE8-
则只要闭包存在,就不回收。(现在的Opera会不会回收,需要看看文档,还有javascriptCore我也不太了解)对于第一个问题:像这样一段代码,在函数 b 没有引用函数 a 里的变量的情况下,函数 b 的作用域链上是否还会包含 函数 a 的作用域?会包含。
一共有以下作用域: 全局>---a>--空的 -->b 其中b能访问任何作用域变量
2.这样,函数 b 内返回了一个闭包出去,这个闭包的作用域链会包含函数 a 的作用域,那么会包含函数函数 b 的作用域吗?
下面的作用域有 全局 --> 空的 --> a --> 空的 -->b --> 闭包(这个闭包能访问任何地方)