16.js的执行环境和作用域

执行环境和作用域
    ***********精髓*************
    当ECMAScript开始执行时,创建一个全局执行环境和全局变量对象;后面每次进入一个函数时(这个函数被调用),则创建一个当前函数的执行环境并压入栈,同时创建此执行环境的变量对象和作用域链,作用域链的创建规则是复制上一层环境的作用域链,并将指向本环境变量对象的指针放到链首;离开函数时,从栈中弹出此执行环境并销毁,同时销毁环境的变量对象和作用域链。
    “当ECMAScript开始执行时,创建一个全局执行环境;每次进入一个函数时(这个函数被调用),则创建一个当前函数的执行环境并压入栈,离开此函数时从栈中弹出此执行环境并销毁。”   ----ECMAScript
    “每一个执行环境有一个与其相关的变量对象,变量对象记录了此执行环境中定义的变量及函数。”    ----ECMAScript
    ************详解************
    一、执行环境(exection context,也有称之为执行上下文)
        所有 JavaScript 代码都是在一个执行环境中被执行的。执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域、生存期等方面的处理,它定义了变量或函数是否有权访问其他数据,决定各自行为。
        在javascript中,可执行的JavaScript代码分三种类型:
            1. Global Code(全局代码),即全局的、不在任何函数里面的代码,例如:一个js文件、嵌入在HTML页面中的js代码等。
            2. Eval Code(Eval代码),即使用eval()函数动态执行的JS代码。
            3. Function Code(函数代码),即用户自定义函数中的函数体JS代码。
        不同类型的JavaScript代码具有不同的执行环境,这里我们不考虑evel code,对应于global code和function code存在2种执行环境:全局执行环境和函数执行环境。
        “当ECMAScript开始执行时,创建一个全局执行环境;每次进入一个函数时(这个函数被调用),则创建一个当前函数的执行环境并压入栈,离开此函数时从栈中弹出此执行环境并销毁。”   ----ECMAScript
        在一个页面中,第一次载入JS代码时创建一个全局执行环境,全局执行环境是最外围的执行环境,在Web浏览器中,全局执行环境被认为是window对象。因此,所有的全局变量和函数都是作为window对象的属性和方法创建的。

        当调用一个 JavaScript 函数时,该函数就会进入与该函数相对应的执行环境。如果又调用了另外一个函数(或者递归地调用同一个函数),则又会创建一个新的执行环境,并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后,执行过程会返回原始执行环境。因而,运行中的 JavaScript 代码就构成了一个执行环境栈。
        “每一个执行环境有一个与其相关的变量对象,变量对象记录了此执行环境中定义的变量及函数。”    ----ECMAScript
        程序在进入每个执行环境的时候,JavaScript引擎在内部创建一个对象,叫做变量对象(Variable Object)。对应函数的每一个参数,在Variable Object上添加一个属性,属性的名字、值与参数的名字、值相同。函数中每声明一个变量,也会在Variable Object上添加一个属性,名字就是变量名,因此为变量赋值就是给Variable Object对应的属性赋值。在函数中访问参数或者局部变量时,就是在variable Object上搜索相应的属性,返回其值。(另外注意:一般情况下Variable Object是一个内部对象,JS代码中无法直接访问。规范中对其实现方式也不做要求,因此它可能只是引擎内部的一种数据结构。)

    二、Scope/Scope Chain(作用域/作用域链)
        
        function Fn1(){
            function Fn2(){
                alert(document.body.tagName);//BODY
                //other code...
            }
            Fn2();
        }
        Fn1();
        //code here
        当代码在一个环境中执行时,都会创建基于Variable Object的一个作用域链。 作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。整个作用域链是由不同执行位置上的Variable Object按照规则所构建一个链表。作用域链的最前端,始终是当前正在执行的代码所在环境的Variable Object。如果这个环境是函数(比如Fn2),则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,就是函数内部的arguments对象。作用域链中的下一个Variable Object来自该函数(Fn2)的包含环境(也就是Fn1),而再下一个Variable object来自再下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的Variable Object始终是作用域链中的最后一个对象。

        如上所述,作用域链感觉就是一个Variable Object链表,当访问一个变量时,先在链表的第一个Variable Object(最前端)上查找,如果没有找到则继续在第二个Variable Object上查找,直到搜索结束,也就是搜索到全局执行环境的Variable Object中。这也就形成了Scope Chain的概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值