Skip to content

JavaScript作用域和执行上下文 #11

@aicekiller

Description

@aicekiller

Javascript作用域

先看两段代码

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope(); // local scope
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()(); // local scope

JavaScript 采用的是词法作用域(lexical scoping),函数的作用域在函数定义的时候就决定了。
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都由函数被声明时所处的位置决定。

执行上下文(Execution Context)

执行上下文可以理解为函数执行的环境,每一个函数调用时,都是在执行上下文中运行。

执行上下文的类型包括:

  • 全局执行上下文:默认的执行上下文,不在任何函数中的代码;
  • 函数执行上下文:当函数被调用时,会生成一个执行上下文,并推入执行上下文栈中;

JavaScript程序中,必定产生多个执行上下文,JavaScript引擎以栈的方式来处理,这个栈,我们称为
函数调用栈(call stack)。栈底永远都是全局上下文,而栈顶则是当前正在执行的函数上下文。

执行上下文的生命周期包括:

  • 创建阶段 在这个阶段中,执行上下文会分别创建变量对象建立作用域链,以及确定this指向;
  • 代码执行阶段 创建完成之后,就会开始执行代码,会完成变量赋值函数引用,以及执行其他代码;

变量对象(Variable Object)

变量对象的创建,依次经历了以下几个过程:

  1. 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。
  2. 检查当前上下文的函数声明(function关键字声明的函数),在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性值已经存在,那么该属性将会被新的引用所覆盖。
  3. 检查当前上下文的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions