资讯专栏INFORMATION COLUMN

javascript:执行环境与作用域链以及函数执行

_ivan / 2904人阅读

摘要:作用域链的末端始终都是全局执行环境的变量对象。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有权访问理解当调用时,函数被定义并作为局部变量绑定到了作用域链上因此函数无论在哪里调用这种绑定依然有效因此返回值为。

执行环境定义

定义了变量或者函数有权访问的其他数据,每个执行环境都有一个与之相关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。我们编写的代码无法访问这个对象,但解析器会在处理数据时在后台使用它。
执行环境的创建

全局执行环境

在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。代码载入浏览器时,全局执行环境被创建(当我们关闭网页或者浏览器时全局执行环境才被销毁)。

局部执行环境

每个函数都有自己的执行环境,因此局部执行环境为函数对象。当函数被调用时函数的局部环境被创建(函数内的代码执行完毕后,该环境被销毁,同时保存在其中的所有变量和函数定义也随之被销毁)。

这个执行环境以及相关的变量对象是个抽象的概念,解释如下

var a = 1;
function fn(num1,num2){
    var b = 2;
    function fnInner(){
        var c = 3;
        alert(a + b + c);
    }
    fnInner();//fnInner调用时局部执行环境创建
}
fn(4,5);//fn调用时局部执行环境创建

                                  图一
                    
                                                                                                             
作用域链

javascript函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的,当定义一个函数时,它实际保存一个作用域链。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的作用域链。作用域链的前端始终都是当前执行的代码所在环境的变量对象。作用域链的末端始终都是全局执行环境的变量对象。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有权访问

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){return scope};
    return f;
}
checkscope()();//local scope

理解:当调用checkscope时,函数f被定义并作为局部变量绑定到了checkscope作用域链上,因此函数f无论在哪里调用,这种绑定依然有效,因此返回值为local scope。

var num1 = 1;
function Outer(){
    var num2 = 2;
    console.log(num1 + num2);//3
    function Inner(){
        //这里可以访问num3,num2,num1
        var num3 = 3;
        console.log(num1 + num2 + num3);//6
        }
    //这里可以访问num2,Inner(),num1但不能访问num3
    Inner();
}
Outer();
console.log(num1);//1,执行环境
//这里只能访问num1

作用域链(向上搜索):内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。

 var name = "Byron";
    function fn(){
        var name = "Csper";
        console.log(name);//Casper
    }
    fn();
    

越往内部的环境,变量权重越高。

注意:没有带var关键字直接声明的变量属于全局变量如直接声明a = 1,此时的a为全局变量。

javscript引擎在进入作用域时,会对代码分两轮处理。第一轮,初始化变量。第二轮,执行代码

var a = 1;
function prison (a) {
    console.log(a);//1
    var a;
    console.log(a);//1
}
prison(1);
函数执行

函数调用进入执行环境时,首先处理arguments,初始化形参(默认值为undefined),然后初始化函数内的函数声明,当代码一步一步执行时再初始化函数内的变量声明(进入环境未开始执行代码时,值为undefined)。所以函数内的初始化顺序为变量声明,函数声明,形参。可以从上图图一看出。下面我来举个例子(整个全局环境也是函数)。

alert(typeof fn);//function,函数声明提前
alert(typeof fn0);//undefined,变量声明提前但未赋值
function fn(){
//函数表达式
}
var fn0 = function(){
//函数定义式
}
alert(typeof fn0);//function,此时变量已被赋值

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85838.html

相关文章

  • 前端基础进阶(四):详细图解作用域链闭包

    摘要:之前一篇文章我们详细说明了变量对象,而这里,我们将详细说明作用域链。而的作用域链,则同时包含了这三个变量对象,所以的执行上下文可如下表示。下图展示了闭包的作用域链。其中为当前的函数调用栈,为当前正在被执行的函数的作用域链,为当前的局部变量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初学JavaScrip...

    aikin 评论0 收藏0
  • 理解JavaScript中的作用域和作用域链

    摘要:示例当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。每一个运行期上下文都和一个作用域链关联。此时,作用域链中函数的所有局部变量所在的作用域对象会被推后,访问代价变高了。 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 作用域链 函数对象有一个内部属性[...

    XanaHopper 评论0 收藏0
  • 由一道题图解JavaScript作用

    摘要:当我将此题的作用域链画出来之后,终于感觉作用域入门了。创建函数的作用域链,并初始化为函数的所包含的对象,即包含了的作用域链。 作用域 为了理解作用域,跪看了好几篇大神的博文,终于略知一二。 1.题目 其中,看到这样一道题(稍作修改): function factory() { var name = laruence; var intro = function(){...

    nevermind 评论0 收藏0
  • JavaScript-作用域-执行上下文-变量对象-作用域链

    摘要:变量对象作用域链因为变量对象在执行上下文进入执行阶段时,就变成了活动对象,因此图中使用了来表示。 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在 JavaScript 中,变量的作用域有全局作用域和局部作用域两种。JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 静态作用域 函数的作用域在函数定义的时候...

    liangzai_cool 评论0 收藏0
  • JavaScript-作用域-执行上下文-变量对象-作用域链

    摘要:变量对象作用域链因为变量对象在执行上下文进入执行阶段时,就变成了活动对象,因此图中使用了来表示。 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在 JavaScript 中,变量的作用域有全局作用域和局部作用域两种。JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 静态作用域 函数的作用域在函数定义的时候...

    MonoLog 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<