`

javascript执行环境及作用域链分析

 
阅读更多

好久没研究javascript了,最近打算换换工作,所以又拿起来回忆一下:

 

直接从我博客里粘过来了希望对初学者有点用处吧,原文地址:http://www.dev26.com/blog/article/208

 

 

执行环境其实就是一个变量或者一个函数有权访问的所有其他数据集合。在每个执行环境中都有一个与之相关联的变量对象(VO),在当前环境中定义的所有变量和函数都会保存在这个变量对象中。VO我们是无法访问的,只有解析器处理数据的时候才有权在后台使用它。

全局执行环境是最外围的环境,一般是window对象,因此我们定义的所有全局变量、函数都被创建为window对象的属性和方法。当某个执行环境中的代码执行完毕,该环境将被销毁,其中的所有变量、函数也同样。

函数在被调用时会创建自己的执行环境,并推入一个栈中。当执行完毕,再弹出以返回到原来的执行环境中去。这个类似于C语言中的函数调用。

作用域链

代码在执行到一个环境中时,会创建由VO构成的作用域链。假如A的执行环境a中调用了函数B产生新的执行环境b,那么b的作用域链最前端将会保存b的VO,链的下面紧接着是它的包含作用域a的VO,如此一直到链的最后是全局执行环境的VO。

标识符的解析器是就是沿着当前环境的作用域链来搜索的。如:

1
2
3
4
5
6
7
var hello = “coomy”;
function say(){
    var hello2 = “ming”;
    alert(hello);
}
say();  //coomy
alert(hello2);  //error 404

当say函数被调用时,对hello进行解析时,会扫描作用域链。首先是自己的VO,发现并没有这个变量,然后开始搜索其上层包含环境的VO,发现了hello。但是外层的作用域中是无法访问其所包含的作用域中的变量的,这些语法都是类似于C语言中的作用域概念。当然,作用域链可以以此类推到多层的嵌套中去。

注意,函数的参数也是被当作变量来对待的,访问规则与执行环境中的其他变量相同。

定义补充一下作用域链

当代码在一个执行环境中执行时(例如一个函数内),会创建由变量对象构成的一个作用域链(scope chain),它是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行代码所在环境的变量对象。如果这个环境是一个函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的,但在一个函数中呢它是这个函数当前活动对象中的第一个属性-activation object.arguments)。作用域链中的下一个对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的变量对象始终都是作用域链中的最后一个对象。标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的最前端开始,然后逐步地向后回溯,直到找到标识符为止(如果找不到标识符,通常会导致错误发生)。

请看以下代码:

1
2
3
4
5
6
7
8
9
10
11
var color = "blue";
function changeColor(){
var a="3";
if(color=="blue" ){
 color="red";
}else{
  color="blue";
}
}
changeColor();
alert("Color is now "+color);

在上面这函数中,函数changeColor()的作用域链包含两个对象:它自己的变量对象(也就是changeColor这个函数的活动对象,对开发人员来说是不可见的只要js解析器短简,当前这函数的活动对象目前有两个属性:arguments和a两个)和全局的变量对象(全局对象中有属性color)。可以在函数内部访问变量color,就是因为可以在这个作用域链中找到它咱们画个简单的图:

在上面的函数中a属性的生命周期是在changeColor函数内部的即函数执行结束变量就会被销毁,如果我们想延长a该怎么办呢;这是一个最简单的闭包了:

1
2
3
4
5
6
7
8
9
function changeColor(){
var a=3;
if(color=="blue" ){
 color="red";
}else{
  color="blue";
}
return a=3;
}

通过以上代码则就可以延长a对象的生命周期.

块级作用域

在C语言中我们知道,一对花括号之间会形成一个新的作用域,也就是新的执行环境。在其中定义的变量,当离开花括号后都会被注销。

但是在javascript中,花括号、if语句、for等这些块级语句在执行完之后,其过程中定义的变量等则不会被注销,而是会被加到其外部的执行环境中去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    var a = 1;
}
if true ) {
    var b = 2;
}
for var c=2; c==2; c++ ){
    var d = 4;
}
while true ) {
    var e = 5;
    break;
}
switch ( a ) {
    case 1: var f = 6;
    defaultvar g = 7;
}
alert('out:'+a+b+c+d+e+f+g);//out:1234567

 用var声明变量会将其加到距离最近的环境中;

未声明的变量被初始化,该变量会被自动加入到全局作用域中;

当前环境的变量等标识符,会覆盖其父环境中的标识符,因为作用域链中当前环境是处在最前面的,也会被最先搜索。当找到时便立即停止向下继续检索。

 


分享到:
评论

相关推荐

    javascript执行环境及作用域详解_.docx

    ### JavaScript执行环境及作用域详解 #### 执行环境概述 执行环境定义了变量或函数能够访问的数据以及其他相关信息,它决定了这些变量和函数的行为方式。在JavaScript中,执行环境的概念至关重要,因为它不仅涉及...

    JavaScript执行环境及作用域链实例分析

    本篇文章将围绕JavaScript的执行环境和作用域链展开,通过实例深入分析这两个概念,并提供一些使用技巧。 首先,执行环境是执行代码的上下文。在JavaScript中,执行环境分为全局执行环境和函数执行环境。全局执行...

    浅谈javascript中执行环境(作用域)与作用域链

    相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享。 一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为...

    JavaScript函数作用域链分析

    JavaScript函数作用域链是理解JavaScript执行环境和变量访问机制的关键概念。作用域链是由作用域构成的链式结构,它决定了变量的查找顺序和访问权限。每个函数在创建时都会与一个作用域链关联,这个链是根据函数的...

    js 函数的执行环境和作用域链的深入解析

    ### JavaScript函数的执行环境与作用域链深入解析 #### 一、引言 JavaScript作为一种广泛应用于Web开发的语言,其灵活性和动态性深受开发者喜爱。在JavaScript中,理解函数的执行环境和作用域链是非常重要的,这...

    JavaScript进阶(二)词法作用域与作用域链实例分析

    在函数执行时,作用域链会根据当前执行环境构建。 2. **变量查找规则**:从最靠近当前执行环境的链开始查找变量,如果没有找到,就向上查找下一个作用域,这个过程一直持续到全局作用域。如果全局作用域也没有找到...

    谈一谈js中的执行环境及作用域

    通过上述分析,我们可以得知JavaScript中的变量作用域规则,以及函数内部如何通过作用域链来访问外部变量,同时也能理解为什么JavaScript中不存在块级作用域。了解这些执行环境和作用域的知识,对于编写结构清晰、...

    JavaScript 作用域链解析

    在深入探讨JavaScript作用域链解析之前,首先需要明确几个关键概念:作用域(Scope)、作用域链(Scopechain)、执行上下文(Executecontext)、活动对象(ActiveObject)、动态作用域(Dynamic Scope)以及闭包...

    浅析JavaScript中作用域和作用域链

    作用域链是由当前执行环境的变量对象和所有包含它的父级执行环境的变量对象组成的链式结构。如果在当前作用域找不到变量,就会向上级作用域查找,直至找到全局作用域。如果在全局作用域仍找不到,变量的值将被视为`...

    JavaScript作用域链实例详解

    JavaScript中的作用域链是理解变量查找机制和函数执行上下文的关键概念。首先,让我们解释一下作用域。在编程中,作用域定义了变量和函数的可访问性,即变量和函数能在哪些地方被引用和使用。 ### 作用域链基本原理...

    闭包作用域

    闭包的形成基于两个关键概念:作用域链(Scope Chain)和执行上下文(Execution Context)。 1. **作用域链**: - 在每个函数创建时,都会构建一个作用域链,用于存储函数可以访问的所有变量和函数。 - 作用域链...

    JavaScript对象模型-执行模型

    引擎还会进行词法分析,识别变量声明、函数定义等,并进行作用域分析。 #### 执行阶段 执行阶段分为全局执行上下文(Global Execution Context)和函数执行上下文。每当执行环境改变,如进入函数,就会创建一个新...

    javascript中eval函数用法分析.docx

    - **局部作用域**: 当`eval()`函数在一个函数内部被调用时,它会访问该函数的作用域链中的变量。 - **全局作用域**: 当`eval()`函数在全局作用域被调用时,它会访问全局变量。 例如: ```javascript var x = 100; ...

    淘宝前端UED资料 javascript

    当函数试图访问某个变量时,它会沿着作用域链逐级查找,直到找到该变量为止。 - **示例:** 函数`d`位于函数`b`内,它可以访问到函数`b`内的变量`c`。这是因为函数`d`的作用域链中包含了`b`的作用域。 **3. 闭包**...

    javascript代码讲解ppt

    #### JavaScript执行环境(ExecutionContext) 在深入了解JavaScript时,我们首先需要明确的是,JavaScript的执行是在特定的上下文中进行的,这种上下文被称为**执行环境**(ExecutionContext)。执行环境是...

    Javascript执行流程细节原理解析

    通过以上分析,我们可以了解到,Javascript引擎的工作机制依赖于执行环境栈、作用域链、变量对象等一系列核心组件。每一段代码的执行都是通过这些组件相互协作完成的。理解这些概念和流程,对于深入掌握Javascript...

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

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

    JavaScript完全手册pdf

    8. **作用域和作用域链**:掌握全局作用域、函数作用域、块级作用域,以及它们之间的关系。 9. **模块化**:学习如何使用CommonJS(Node.js环境)和ES6的import/export进行模块管理。 10. **错误处理**:理解try.....

Global site tag (gtag.js) - Google Analytics