在JavaScript中,变量对象、函数调用栈、作用域和闭包是非常重要的概念。理解它们有助于我们更好地理解JavaScript代码的执行过程,从而写出更优秀的代码。
变量对象
每一个执行上下文都有一个与之关联的变量对象(VO),它存储了在该上下文中定义的变量、函数声明和函数参数。在全局上下文中,变量对象被称为全局对象。在函数上下文中,变量对象被称为活动对象(AO)。
当JavaScript引擎进入一个执行上下文时,它会创建一个新的变量对象,并将其推入到上下文的作用域链的顶端。变量对象包含了所有在该上下文中定义的变量、函数声明和函数参数。如果一个变量没有在当前上下文中定义,那么它就不在该上下文的变量对象中。
以下是一个示例代码:
-- -------------------- ---- ------- --- - - -- -------- ----- - --- - - -- --------------- -- - --------------- -- - - ------
在这个示例中,全局上下文的变量对象包含一个名为"a"的变量,它的值为1。当函数"foo"被调用时,它创建了一个新的上下文,并在该上下文中创建一个变量对象。该变量对象包含一个名为"b"的变量,它的值为2。在函数内部,代码可以访问全局变量"a"和局部变量"b"。
函数调用栈
JavaScript引擎使用函数调用栈来跟踪正在执行的所有函数。当一个函数被调用时,它会被推入到调用栈的顶部。当函数执行完成后,它会从调用栈中弹出。每个执行上下文都对应着调用栈中的一个帧。
以下是一个示例代码:
-- -------------------- ---- ------- -------- ----- - ------------------- - -------- ----- - ------ ------------------- - ------
在这个示例中,调用栈将依次包含三个帧:全局上下文、函数"bar"的上下文和函数"foo"的上下文。当函数"foo"完成执行后,它的上下文被弹出,控制权返回到函数"bar"。当函数"bar"执行完毕后,它的上下文也被弹出,控制权最终返回到全局上下文。
作用域
作用域决定了代码中的变量和函数在哪些地方可见。在JavaScript中,作用域是通过词法作用域实现的,也就是说,作用域是由代码嵌套关系所定义的,而不是由代码执行顺序所定义的。
在JavaScript中,每个函数都有一个词法作用域链。该作用域链包含了所有其父级函数和全局上下文的变量对象。当查找一个变量时,JavaScript引擎会首先搜索当前上下文的变量对象,如果没有找到该变量,则继续向上搜索父级函数和全局上下文的变量对象,直到找到该变量或者到达作用域链的末尾。
以下是一个示例代码:
-- -------------------- ---- ------- --- - - -- -------- ----- - --- - - -- -------- ----- - --- - - -- --------------- -- - --------------- -- - --------------- -- - - ------ - ------
在这个示例中,函数"bar"的作用域链包
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/34525