JavaScript核心原理(一)执行环境、执行环境栈、变量对象、活动对象
来源:互联网 发布:2017淘宝怎么装修教程 编辑:程序博客网 时间:2024/05/17 21:49
前言
“每当程序的执行流进入到一个可执行的代码时,就进入到了一个执行环境中。”
执行环境是 ECMA-262 中用以区分不同的可执行代码的抽象概念
可执行代码的类型可以为分为:
- 全局代码:程序载入后的默认环境,是运行在程序级别的代码。
- 函数代码:当执行流进入一个函数后。
- Eval代码:Eval 内部的代码。
#
执行环境栈(Execution Stack)
执行流依次进入的执行环境在逻辑上形成了一个栈,栈的底部永远是全局环境,栈的顶部则是处于活动状态当前的执行环境(浏览器总是执行处于栈顶的上下文)。当执行流进入一个函数时,函数的环境就会被推入这个环境栈中,当函数执行完毕之后,栈将这个执行环境弹出,然后把控制权返回给之前的执行环境。这样实现的原因是由于 Javascript 解释器是单线程的,也就是同一时刻只能发生一件事情,其他等待执行的上下文或事件就会在这个环境栈中排队等待。值得注意的一点是:每次函数的调用都会创建一个执行环境压入栈中,无论是函数内部的函数、还是递归调用等。
每一个执行环境都有一个与之相关的变量对象,其中存储着上下文中声明的:
- 变量 VariableDeclaration VD
- 函数 FunctionDeclaration FD
- 形式参数 formal parameters
全局对象是一个在进入任何执行上下文前就创建出来的对象;此对象以单例形式存在;它的属性在程序任何地方都可以直接访问,其生命周期随着程序的结束而终止。
全局对象的属性在任何地方都可以被访问到,可以通过 this 或者 DOM 中的 Window 对象来访问。全局对象中的变量对象就是全局对象本身,理解这一点很重要,正是因为这个原因才使得可以通过全局对象的属性来访问在全局上下文中声明的变量。
函数上下文中的变量对象
当函数被调用时,一个特殊的对象——活动对象就随之创建了。变量对象通过函数的 arguments 对象来初始化,arguments 对象是活动对象上的属性,包含了以下属性:
- callee 对当前函数的引用
- length 传入的实参个数
- properties-indexes 参数对应的索引值,相应的值和实际传入的参数值是共享的,但不并是存储在同一个地方的
执行环境的具体细节
- 第一步:创建阶段 (在函数调用之后,函数体执行之前),解释器扫描传递给函数的参数或arguments,本地函数声明和本地变量声明,并创建executionContextObj对象。扫描的结果将完成变量对象的创建
*创建作用域链 (Scope Chain) 扫描上下文中声明的形式参数、函数以及变量,并依次填充变量对象的属性
函数的形参:形参作为属性,对应的实参作为值。对于没有实参的形参,值为undefined。
- 函数声明(FunctionDeclaration FD):由函数对象创建出相应的名、值,名就是函数名、值就是函数体。如果变量对象已经包含了同名的属性,就会替换掉它的值。
- 变量声明(VariableDeclaration):属性名是变量名,值初始化为 undefined。如果变量名和已经存在的属性同名,不会影响到同名的属性。
注意:函数表达式(FunctionExpression FE)不会成为变量对象的属性,也就是说函数表达式不会影响到变量对象。
求出上下文“this”的值
第二步:代码执行阶段
- 这一阶段就会给第一步中初始值为 undefined 的变量赋上相应的值
我们来看下面这个例子:
- 这一阶段就会给第一步中初始值为 undefined 的变量赋上相应的值
现在你应该非常清楚JS中的变量、函数声明提升是怎么回事了吧。
最后,再来说说关于变量声明的问题:
在《Javascript高级程序设计》4.2.2一节当中有这么一句话:“如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境中。” 首先,我们应该先明确一点,使用var关键字是声明变量的唯一方式。如果没有var 的话,例如 a = 5 ,a 就将作为全局对象的一个属性,而不是一个变量。
文章参考:
- ECMA-262-3 in detail. Chapter 1. Execution Contexts. |中文版
- ECMA-262-3 in detail. Chapter 2. Variable object. |中文版
- What is the Execution Context & Stack in JavaScript? | 中文版
- JavaScript核心原理(一)执行环境、执行环境栈、变量对象、活动对象
- JavaScript 执行环境 与 变量对象
- JavaScript执行环境和执行环境对象
- JavaScript核心:对象 原型链 构造函数 执行上下文栈 执行上下文 变量对象 活动对象 作用域链 闭包 This 总结
- JavaScript中的执行环境、变量对象和作用域链
- JavaScript变量对象、执行环境和作用域链
- Javascript 作用域链 活动对象 执行环境 与 this 的纠结 总结~
- Javascript 作用域链 活动对象 执行环境 与 this 的纠结 总结~
- Javascript 作用域链 活动对象 执行环境 与 this 的纠结 总结~
- 执行环境,作用域链、活动对象的关系
- JavaScript速记5 —— 执行环境、变量对象和作用域链
- 深入Javascript函数与闭包(执行环境、变量对象与作用域链)详解
- 深入Javascript函数与闭包(执行环境、变量对象与作用域链)使用详解
- 理解执行环境、作用域链和活动对象 (转载)
- 执行环境和对象上下文
- 执行环境和对象上下文
- 执行上下文中的变量对象和活动对象
- JavaScript 执行上下文和变量对象
- 精通 CSS+DIV 网页样式与布局 89
- input
- 精通 CSS+DIV 网页样式与布局 90
- 【深入分析Java多线程】(6)线程间通信之wait()、notify()、join()
- Python sys中的sys.argvp[] 和 os.popen()方法
- JavaScript核心原理(一)执行环境、执行环境栈、变量对象、活动对象
- git 常用命令
- C语言笔记(5)
- eclipse批量修改变量
- 学习java
- log4j的一些知识
- Java基础----ThreadLocal
- android之FragmentPagerAdapter 和FragmentStatePagerAdapter的区别
- python 学习笔记7进程和线程