`

深入--作用域链

 
阅读更多

接着《深入--变量对象》讲讲作用域链

 

作用域链

 

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

 

下面,让我们以一个函数的创建和激活两个时期来讲解作用域链式如何创建和变化的

 

创建函数

 

函数的作用域在函数定义的时候就决定了

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

 

举个例子:

function foo(){
   function bar(){
       ...
   }
}

 函数创建时,各自的[[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]] = [
      globleContext.VO
];

 2.执行checkscope函数,创建checkscope函数执行上下文,该上下文被压入执行上下文栈

ECStack = [
   checkscopeContext,
   globalContext
];

 3.checkscope函数不立即执行,开始做准备工作,第一步:复制函数[[scope]]属性创建作用域链

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

 4.第二步:用arguments创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明

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

 5.第三步:将活动对象压入checkscope作用域链顶端

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

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

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

 

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

ECStack = [
    globalContext
];

 

 

 

分享到:
评论

相关推荐

    深入理解JavaScript作用域和作用域链

    深入理解JavaScript作用域和作用域链对于编写高效、无错的代码至关重要。正确管理作用域可以避免全局变量冲突,提高代码的复用性和模块化,同时也有助于提升性能,因为局部变量的访问速度通常比全局变量快。在实际...

    深入理解变量作用域

    - 当JavaScript引擎需要查找变量时,它会从当前作用域开始,沿着作用域链向上查找,直到找到相应的变量为止。 - 如果在当前作用域找不到变量,则继续在上一层作用域中查找,依此类推,直到到达全局作用域。 - 这...

    深入了解JavaScript,优化作用域链(2).pdf

    下面我们从多个方面来详细探讨作用域链的概念、作用域链的层级关系、变量访问的性能影响,以及如何通过优化作用域链来提升程序性能。 首先,作用域是编程中一个基本的概念,它决定了变量和函数的可访问范围。在...

    夯实基础中篇-图解作用域链和闭包.doc

    在JavaScript编程中,作用域链和闭包是两个至关重要的概念,它们对于理解代码执行机制以及函数内部如何访问和管理变量至关重要。让我们深入探讨这两个概念。 首先,**作用域链**是JavaScript中的一种机制,它定义了...

    JavaScript程序设计-变量作用域.pdf

    本文将深入探讨JavaScript中的全局变量、局部变量、变量提升、词法作用域以及作用域链。 1.1 全局变量与局部变量 全局变量在整个程序中都可访问,即使在函数内部定义,它们也会成为全局变量,除非在函数内部重新...

    深入了解JavaScript,从作用域链开始(1).pdf

    总的来说,深入理解JavaScript的作用域和作用域链对于编写高效、无bug的代码至关重要。通过掌握这些基本概念,开发者可以更好地管理变量和函数的生命周期,避免全局变量的滥用,并有效地组织代码逻辑。

    005课-继承作用域闭包.rar

    2. **作用域的详解**:解释不同类型的变量作用域,如全局作用域、局部作用域和块级作用域,并通过实例展示作用域规则。 3. **闭包的原理**:解释什么是闭包,如何创建闭包,以及闭包如何保持对外部变量的引用。 4....

    JavaScript中作用域链的概念及用途讲解

    在深入理解作用域链之前,我们首先要了解什么是执行环境和变量对象。 执行环境,简单来说,就是代码执行时所在的上下文。在JavaScript中,每个执行环境都有一个与之关联的变量对象,它包含了该环境中定义的所有变量...

    javascript 闭包、匿名函数、作用域链

    JavaScript中的闭包、匿名函数和作用域链是编程中至关重要的概念,它们是理解JavaScript运行机制的关键。在本文中,我们将深入探讨这三个概念,并通过实际示例来展示它们的运用。 首先,我们来讨论“闭包”。闭包是...

    深入理解JavaScript作用域共12页.pdf.zip

    作用域链决定了一个作用域如何查找变量,它是由当前执行环境与所有包含它的父级环境构成的链式结构。这个链对于理解函数调用和执行上下文至关重要。 此外,箭头函数(`=>`)在处理作用域方面有别于传统的函数表达式...

    js代码-闭包与作用域,经典题

    2. **作用域链**:闭包的实现依赖于JavaScript的作用域链,每个函数都有一个作用域链,用于查找变量。内部函数的作用域链不仅包含自身的变量,还包括外部函数的作用域。 3. **内存管理**:由于闭包,外部函数的变量...

    JavaScript — 原型链与作用域链1

    JavaScript是一种广泛用于网页和网络应用的脚本语言,它的核心特性包括原型链和作用域链。...总结来说,JavaScript的原型链和作用域链是其灵活性和强大功能的基础,理解它们对于深入学习和优化JavaScript代码至关重要。

    javascript作用域链(Scope Chain)初探.docx

    JavaScript的作用域链是一个重要的概念,尤其是在深入理解JavaScript执行机制时不可或缺的一部分。本文将通过对几个具体例子的分析来探讨JavaScript作用域链的基本原理及其工作方式。 #### 二、从一个简单的问题...

    js作用域基本介绍.doc

    作用域链是一种查找规则,用于确定变量的位置。它是由当前作用域到全局作用域的一系列作用域构成的链,用于在执行过程中查找变量。查找始终从当前作用域开始,向上逐层检查,直到找到变量或者到达全局作用域。 4. ...

    Javascript作用域和作用域链原理解析

    理解JavaScript的作用域和作用域链对于编写健壮、可维护的代码至关重要。它可以帮助开发者更好地管理变量,减少错误,并提高代码的可读性和可预测性。深入掌握这些概念,将使你成为一名更出色的JavaScript开发者。

Global site tag (gtag.js) - Google Analytics