VO、AO、执行环境和作用域链
1、变量对象(variable object)
原文:Every execution context has associated with it a variable object. Variables and functions declared in the source text are added as properties of the variable object. For function code, parameters are added as properties of the variable object.
简言之就是:每一个执行上下文都会分配一个变量对象(variable object),变量对象的属性由 变量(variable) 和 函数声明(function declaration) 构成。在函数上下文情况下,参数列表(parameter list)也会被加入到变量对象(variable object)中作为属性。变量对象与当前作用域息息相关。不同作用域的变量对象互不相同,它保存了当前作用域的所有函数和变量。
这里有一点特殊就是只有 函数声明(function declaration) 会被加入到变量对象中,而 **函数表达式(function expression)**则不会。看代码:
// 函数声明
function a(){}
console.log(typeof a); // "function" // 函数表达式
var a = function _a(){};
console.log(typeof a); // "function"
console.log(typeof _a); // "undefined"
函数声明的方式下,a会被加入到变量对象中,故当前作用域能打印出 a。
函数表达式情况下,a作为变量会加入到变量对象中,_a作为函数表达式则不会加入,故 a 在当前作用域能被正确找到,_a则不会。
2、活动对象(activation object)
原文:When control enters an execution context for function code, an object called the activation object is created and associated with the execution context. The activation object is initialised with a property with name arguments and attributes { DontDelete }. The initial value of this property is the arguments object described below.
The activation object is then used as the variable object for the purposes of variable instantiation.
简言之:当函数被激活,那么一个活动对象(activation object)就会被创建并且分配给执行上下文。活动对象由特殊对象 arguments 初始化而成。随后,他被当做变量对象(variable object)用于变量初始化。
用代码来说明就是:
function a(name, age){
var gender = "male";
function b(){}
}
a(“k”,10);
a被调用时,在a的执行上下文会创建一个活动对象AO,并且被初始化为 AO = [arguments]。随后AO又被当做变量对象(variable object)VO进行变量初始化,此时 VO = [arguments].concat([name,age,gender,b])。
作用域是指程序源代码中定义变量的区域。
作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。
JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。
(1)静态作用域与动态作用域
因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。
而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。
让我们认真看个例子就能明白之间的区别:
var value = 1; function foo() {
console.log(value);
} function bar() {
var value = 2;
foo();
} bar(); // 结果是 ???
假设JavaScript采用静态作用域,让我们分析下执行过程:
执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。
而引用《JavaScript权威指南》的回答就是:
JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效。
4、执行环境和作用域链(execution context and scope chain)
execution context
顾名思义 执行环境/执行上下文。在javascript中,执行环境可以抽象的理解为一个object,它由以下几个属性构成:executionContext:{
variable object:vars,functions,arguments,
scope chain: variable object + all parents scopes
thisValue: context object
}此外在js解释器运行阶段还会维护一个环境栈,当执行流进入一个函数时,函数的环境就会被压入环境栈,当函数执行完后会将其环境弹出,并将控制权返回前一个执行环境。环境栈的顶端始终是当前正在执行的环境。 !通俗来讲,就是: 当执行一个函数的时候,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。
执行上下文的代码会分成两个阶段进行处理:分析和执行,我们也可以叫做:
- 进入执行上下文(当进入执行上下文时,这时候还没有执行代码)
- 代码执行 (在代码执行阶段,会顺序执行代码,根据代码,修改变量对象的值)
scope chain
作用域链,它在解释器进入到一个执行环境时初始化完成并将其分配给当前执行环境。每个执行环境的作用域链由当前环境的变量对象及父级环境的作用域链构成。
作用域链具体是如何构建起来的呢,先上代码:function test(num){
var a = "2";
return a+num;
}
test(1);- 执行流开始 初始化function test,test函数会维护一个私有属性 [[scope]],并使用当前环境的作用域链初始化,在这里就是 test.[[Scope]]=global scope.
- test函数执行,这时候会为test函数创建一个执行环境,然后通过复制函数的[[Scope]]属性构建起test函数的作用域链。此时 test.scopeChain = [test.[[Scope]]]
- test函数的活动对象被初始化,随后活动对象被当做变量对象用于初始化。即 test.variableObject = test.activationObject.contact[num,a] = [arguments].contact[num,a]
- test函数的变量对象被压入其作用域链,此时 test.scopeChain = [ test.variableObject, test.[[scope]]];
至此test的作用域链构建完成。
VO、AO、执行环境和作用域链的更多相关文章
- JavaScript之一: 闭包、执行环境、作用域链
这是大虾的第一篇博文,大虾试图用最直白的语言去描述出所理解的东西,大虾是菜鸟,水平有限,有误的地方希望路过的朋友们务必指正,谢谢大家了. 从读书时代一路走来,大虾在学习的时候逐渐喜欢上了去追寻根源,这 ...
- Javascript执行环境、作用域链
执行环境 可以把执行环境想象为一个圆圈,里面包含了一些变量.函数. 执行环境定义了变量或函数的有权访问的其他数据,决定了它们各自的行为.还有一个顶部执行环境.在浏览器中,顶部执行环境既为window, ...
- javascript基础进阶——执行环境及作用域链
概念 执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局 ...
- javascript中函数的执行环境、作用域链、变量对象与活动对象
javascript高级程序设计中:对执行环境.作用域链.变量对象.活动对象的解释: 1.执行环境: 执行环境:有时也叫环境:是JavaScript中最为重要的一个概念:执行环境定义了变量或函数有权访 ...
- javaScript执行环境、作用域链与闭包
一.执行环境 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为:每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象 ...
- JavaScript:理解执行环境、作用域链和活动对象
作用域的原理,对JS将如何解析标识符做出了解答.而作用域的形成与执行环境和活动对象紧密相关. 我们对于JS标识符解析的判断,存在一个常见误区 首先,看一个关于JS标识符解析的问题 ,源于风雪之隅提出的 ...
- 深度剖析Javascript执行环境、作用域链
一.执行环境 执行环境(也叫做执行上下文,Execution Context)是Javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问其他数据,决定了它们各自的行为.每个执行环境都 ...
- JavaScript 执行环境以及作用域链
执行环境(execution context,为简单起见,有时也称为"环境")是 JavaScript 中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们 ...
- JS执行环境,作用域链及非块状作用域
JS中的执行环境,顾名思义就是变量或函数所执行时的环境.在我的理解中,执行环境和作用域相差不大. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而在函数执行之后 ...
随机推荐
- js的中文在网页中显示为乱码
最近的毕业设计写道局部检查用户命是否为空和是否符合规范时 发现页面回显的中文为乱码 then 找到一个和我遇到同样问题的人呐 他说“最近在写一个商城网页的时候遇到了一个问题,那就是javascrip ...
- Nginx配置文件及模块解析
一.Nginx是什么? Nginx是一个基于c语言开发的高性能http服务器及反向代理服务器.由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu.内 ...
- struts1与struts2的区别。
1) 两个框架都是MVC的WEB框架, 2) struts1是老牌框架,应用很广泛,有很好的群众基础,使用它开发风险很小,成本低,Struts2核心设计思想主要源自Webwork,实现更优雅,更容易扩 ...
- --save-dev --save 的区别
--save 是发布会还在使用 --save-dev 是在开发中需要用到的 --save 依赖的文件在denpendencis下 --save-dev 依赖的文件都在dvedependencis下
- [Err] 1093 - You can't specify target table 'master_data' for update in FROM clause
delete from master_data where category_id not in (select category_id from master_data a, bc_category ...
- eregi
eregi (PHP 4, PHP 5) eregi — 不区分大小写的正则表达式匹配 说明 int eregi ( string $pattern , string $string [, array ...
- JAVA中时间格式(SimpleDateFormat)和数字格式(DecimalFormat)转换详解(转)
时间格式转换SimpleDateFormat: //定义日期的格式 SimpleDateFormat format =new SimpleDateFormat("yyMMdd"); ...
- CTF资料
题目大概有这么几个 web,密码学,pwn(综合渗透),misc(杂项),reverse(逆向),ppc(编程类) 入门: http://bobao.360.cn/ctf/ 360的CTF训练营ww ...
- UnityShader实现物体被遮挡描边
之前在网上看到物体遮挡描边的功能,自己也拿来实现了一番.算作第一篇博客的开篇. 先贴出几张效果图,也是个人思路和方案的改进路线吧. ////////////////////////////////// ...
- 记录linux配置
只写成功过程:1.配置sshd: 首先开启安全组端口,选择合适端口(tcp),shell输入vi /etc/services ->ssh修改(21变更为合适端口) 接着shell输入vi /et ...