首页 > js作用域链的问题

js作用域链的问题

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上试了一下,确实,语句结尾加分号吧(写代码好习惯);

既然有疑问 ,那就写代码验证一下呗。

(function a() {
    var propa = 'a';
    
    (function b() {
        var propb = 'b';
        
        return function () {
            var propc = propa ;
            console.log('我能拿到propa么:'+propc);
            console.log('b呢:'+propb);
        }
    })()();//返回了一个function别忘了运行~
})()

  1. 对于第一个问题:像这样一段代码,在函数 b 没有引用函数 a 里的变量的情况下,函数 b 的作用域链上是否还会包含 函数 a 的作用域?会包含。
    一共有以下作用域: 全局>---a>--空的 -->b 其中b能访问任何作用域变量

function a() {
    var propa = 'a';
    
    (function b() {
        var propb = 'b';
    })();
}
a();

2.这样,函数 b 内返回了一个闭包出去,这个闭包的作用域链会包含函数 a 的作用域,那么会包含函数函数 b 的作用域吗?

下面的作用域有 全局 --> 空的 --> a --> 空的 -->b --> 闭包(这个闭包能访问任何地方)

(function a() {
            var propa = 'a';
            
            ((function b() {
                var propb = 'b';
                
                return function () {
                    var propc = propa ;
                    var propd =  propb ;
                    console.log(propc);
                    console.log(propd);
                };
           //调用返回的闭包 控制台输出了a, b 说明了能访问其他的作用域。
            })())();
        })();

我来以规范的角度回答这个问题,从规范来解释这个问题是最权威、最正确的。

我们都知道,(规范上)函数运行时,会有一个执行环境对象push到执行栈顶部,这个执行环境包括词法环境,可以把词法环境理解为执行环境的一个属性。

下面,我们来看,什么是词法环境,根据规范:

一个词法环境由一个环境记录项和可能为空的外部词法环境引用构成。

环境记录项:是一个对象,在函数中你声明的propa/propb/propc和未声明的arguments等变量都是这个对象的属性

外部词法环境引用: 作用域链就是由它链起来的。

由规范可看出

第一个回答:会。因为规范没说不会。

第二个回答:会。因为规范没说不会。

关于闭包变量回收: 其实,现在的js引擎是特别特别聪明的V8/SpiderMonkey/IE9+用的查克拉等引擎会把没有用到,将来也不可能用到的变量回收掉了,而早期Opera/IE8-则只要闭包存在,就不回收。(现在的Opera会不会回收,需要看看文档,还有javascriptCore我也不太了解)


In JavaScript, scope is the set of variables, objects, and functions you have access to.

function a() {
    var propa = 'a';
    
    (function b() {
        var propb = 'b'
    })();
}
a()

函数 b 中虽然没有引用函数 a 的任何变量,但是他的确有能力访问到函数a的任何变量,为什么不能说函数 b 的作用域链上是否还会包含 函数 a 的作用域呢?
第二段代码一样道理。

【热门文章】
【热门文章】