• 深入理解javascript中执行环境(作用域)与作用域链


    深入理解javascript中执行环境(作用域)与作用域链

      相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享。

      一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境。那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境。我们下来看一看如下代码,再进一步分析之。

    <script>
    var name="zhuzhenwei"; function changeName(){ if (name=="zhuzhenwei"){ name="heting"; }else{ name="zhuzhenwei"; } } changeName(); console.log(name); //heting
    </script>

      如上述代码,当执行第一个语句时,该语句所在的环境为全局执行环境,应当注意的是:每个执行环境都有一个与之相关联的变量对象,对于全局执行环境,与它向关联的对象为window对象。紧接着,下面这条语句声明了一个函数(注意:这里仅仅是声明了函数,没有被调用之前是不会执行内部代码的)。  同样这个函数也是处于全局执行环境的。最后,我们调用了changeName()函数,一旦调用了该函数,那么立即跳转到了changeName()函数的执行环境(即函数执行环境),一旦进入执行环境,便开始创建函数内部相应的变量(如函数中假设出现var a=12;这样的代码),不调用函数是不会创建的,且与之相关的变量对象我们认为是活动对象(活动对象开始只包含一个变量,即arguments对象),自此开始从上到下执行语句。与此同时,代码在函数环境中执行时,就会创建变量对象的一个作用域链,这个作用域链包含changeName()的变量对象和全局变量对象。

       作用域链实际上就是我们可以通过它从前端到末端可以访问的范围,即保证对执行环境有权访问的所有变量和函数的有序访问,其中前端是指当前执行代码所在的变量对象,这里现在就是changeName()函数的变量对象,末端是全局变量对象,比如说:我们在执行函数时,需要寻找一个标识符,这是就是通过作用域链的末端进行寻找,若作用域链的末端找不到,就一直向上寻找,直到window对象。虽然在全局环境中我没有提到作用域链,但实际上全局环境中作用域链也是存在的,只是只有一个全局变量对象。 很明显:访问局部变量比访问全局变量更快,因为不用向上搜索作用域链。显然,作用域链是随着代码所处的执行环境的不同而动态变化的。            

      当执行完changeName()函数之后,即函数执行环境中的代码执行完成之后,该环境中的局部变量和局部对象会被立即销毁(如果变量没有用var声明,表明是全局变量,不会在局部环境的代码执行之后销毁),随即执行环境由函数执行环境转向全局执行环境,继续执行console.log(name);语句。只是,如果我们关闭网页或浏览器,全局环境也将被销毁。

       总结如下:

    • 执行环境也成为作用域,执行环境决定了变量的生命周期。
    • 执行环境有全局执行环境和局部执行环境之分,每进入一个执行环境就会创建一个用于搜索变量和函数的作用域链,于是我们认为这个作用域链是动态变化的。
    • 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含环境(父环境),乃至全局环境;而全局环境只能访问在全局环境中定义的变量和函数(局部环境中未使用var声明的变量也属于全局变量),不能访问局部环境中的数据(没有说所有数据,正是因为全局变量可以访问)。注意:函数中的参数时函数的局部变量。

    世界上本没有路,你走过去了,那便是你的路。

  • 相关阅读:
    C# 操作Orcle数据库
    WinDbg排查CPU高的问题
    NetCore微服务实战体系:日志管理
    NetCore微服务实战体系:Grpc+Consul 服务发现
    解惑求助-关于NetCore2.2中间件响应的问题
    EF Join连接查询的坑
    给DataTable添加行的几种方式
    [C#] 折腾海康威视的人体测温 模组
    [WPF 学习] 15.播放百度合成的语音
    [WPF 学习] 14.PlaceHolder的简单实现
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6013167.html
Copyright © 2020-2023  润新知