您的位置:首页 > Web前端 > JavaScript

javascript执行上下文、作用域与闭包(第三篇)---自由变量与作用域链

2017-10-14 17:18 661 查看
首先解释一下,什么是自由变量。

在A作用域中使用的变量x,却没有在A作用域中声明(即在其他作用域中声明的),对于A作用域来说,x就是一个自由变量。简单的说,凡是跨了自己的作用域的变量都叫自由变量。如:

var x=10;
function foo()
{
var b=20;
alert(x+b); //这里x就是自由变量
}
foo();//30


在调用fn()函数时,函数体中第6行。取b的值就直接可以在fn作用域中取,因为b就是在这里定义的。而取x的值时,就需要到另一个作用域中取。到哪个作用域中取呢?

这时你可能就说,到上一级作用域去取值啊,(到上一级作用域里取值就涉及到了作用域链的概念),但是这种说法是有歧义的,下面的例子就说明了这个歧义(为什么说是歧义呢?);

var aa = 22;
function a(){
alert(aa);
}
function b(fn){
var aa = 11;
fn();
}
b(a); //22


按照一般思路来讲,到上一级作用域取值,结果应该是11,为什么结果是22,而不是11呢?这就是这个歧义,不是说到上一级作用域取值有问题,而是到哪一个上一级作用域取值?

在上一篇 javascript执行上下文、作用域与闭包(第二篇)—作用域里我有提到一个很重要的作用域的特点:作用域是在函数创建的时候就已经确定了,而不是函数调用的时候。

所以,在上面的例子里函数a()的上一级作用域是全局作用域,而不是函数b()的作用域,故到上一级作用域取到的变量aa的值是22,而非11.

所以,我们要铭记:要到创建函数a()的那个作用域中取——而不管函数a()是在哪里调用.

上面描述的只是上一级作用域就找到了变量,但是如果上一级作用域没有找到了,那就再上一级,如果再没有,就再上一级,直到全局作用域,如果全局作用域没有,那就真的没有了,并且,每上一级作用域取值都是到创建这个函数的作用域去取值。

所以我们可以看到,作用域链是因为自由变量才存在的,也是因为自由变量,作用域链才有意义。

那么,在结尾我再为下一篇埋下一个伏笔,我们是真的在作用域里取值吗?

我们在上一篇说过,作用域只是一个范围,里面并没有变量,其实是在作用域对应的执行上下文取值,可能同样的作用域,相同的变量取到的值是不同的,那么下一篇将会详细讲解作用域和执行上下文的关系。

下一篇: javascript执行上下文、作用域与闭包(第四篇)—作用域与执行上下文

本文参考了王福朋老师的深入理解javascript原型和闭包(14)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐