JavaScript基础之作用域与作用域链

作用域和作用域链是JavaScript中最基础的点,但是也是比较难的点,那么我们就来系统的讲解一下:

作用域:作用域就是指程序源代码中定义变量的区域。作用域规定了如何查找变量,也就是当前执行代码对变量的访问权限。

JavaScript采用的是词法作用域,也就是静态作用域。也就是函数的作用域在函数定于的时候就决定了。而与静态作用域相对的是动态作用域,只有在函数被调用的时候才决定的。

那么如何查找变量呢?这就是所谓的作用域链。

作用域链:当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。

我们来看个例子:

function foo () {
    function bar () {
        //    do something
    }
}

我们知道JavaScript是静态作用域,在函数的作用域是在函数被定义的时候决定的。这是因为函数有一个内部属性 [[scope]],当函数创建的时候,就会保存所有父变量对象到其中,你可以理解 [[scope]] 就是所有父变量对象的层级链,但是注意:[[scope]] 并不代表完整的作用域链!

foo.[[scope]] = [
  globalContext.VO
];

bar.[[scope]] = [
    fooContext.AO,
    globalContext.VO
];

当函数被激活后,进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用链的前端。这时候执行上下文的作用域链,我们命名为 Scope:

Scope = [AO].concat([[Scope]]);

至此,作用域链创建完毕。 

下面以一个例子来总结一下整个过程:

var scope = "global scope";
function checkscope(){
    var scope2 = 'local scope';
    return scope2;
}
checkscope();

(1)checkscope函数创建,将作用域链保存到函数内部的[[scope]]中

checkscope.[[scope]] = [
    globalContext.VO
];

(2)执行checkscope,创建checkscope函数的执行上下文,并且压入到执行上下文栈中

ECStack = [
    checkscopeContext,
    globalContext
];

(3)checkscope并不会立即执行:开始准备工作:

              (一)复制函数[[scope]]属性创建作用域链

checkscopeContext = {
    Scope: checkscope.[[scope]],
}

              (二)用 arguments 创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: undefined
    },
    Scope: checkscope.[[scope]],
}

              (三)将活动对象压入 checkscope 作用域链顶端

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: undefined
    },
    Scope: [AO, [[Scope]]]
}

 

(4)准备工作做完,开始执行函数,随着函数的执行,修改 AO 的属性值

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: 'local scope'
    },
    Scope: [AO, [[Scope]]]
}

(5)查找到 scope2 的值,返回后函数执行完毕,函数上下文从执行上下文栈中弹出

ECStack = [
    globalContext
];

以上就是作用域和作用域链的相关内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值