• JS执行环境,作用域链及非块状作用域


           JS中的执行环境,顾名思义就是变量或函数所执行时的环境。在我的理解中,执行环境和作用域相差不大。

    每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,

    栈将其环境弹出,把控制权返回给当前的执行环境。简单点来说,就像C语言中的栈,当一个函数被运行时,它总是先运行

    最内部的函数(也就是局部函数),再一层一层的向外部执行,就像一个栈一样,后进先出。

           当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链好像一把梯子,最外层的(全局环境)永远是

    最高那节梯子,每在上一个环境下增加一个变量对象,梯子下面就增加一节,就像一层一层嵌套下去。并且这梯子只能往上爬

    不能往下走。

         下面来看一个例子吧!

       var color = "blue";

       function changeColor(){

            var anotherColor = "red";

            function swapColor(){

                 var tempColor = anotherColor;

                 anotherColor = color;

                 color = tempColor;

              //这里可以访问color,anotherColor,tempColor

            }

          //这里可以访问color和anotherColor和tempColor

          SwapColors();

      }

    //这里只能访问color

    changeColor();

    在这个例子中实现了局部变量和全局变量互换使用。

    以上代码共涉及了3个执行环境:全局环境、changeColor()的局部环境和swapColor()的局部环境。

    该例子的作用域链如下:

       window----

                   ----color

                   ----changeColor()

                                               ----anotherColor

                                               ----swapColor()

                                                                       ----tempColor

    从该图可以很明显看出他们之间的嵌套关系。tempColor就是我所说的梯子中最下面的那一节,他可以一直往上爬

    访问外部的变量,但外部的变量不能往下访问内部变量。就像color变量环境下不能访问anotherColor一样。

    当然我们也可以通过某种手段来延长作用域链

    我们可以使用try-catch语句的catch块;或者with语句来延长作用域链

    例如:

    function build(){

       var qs = "hello";

       width(location){

           var url = href +qs;

        }

    return url;

    }

      在这里url变量可以下一个阶梯在with领域中使用。

    接下来我们谈下JS中的非块级作用域

    JS不想C、JAVA这类语言,JS是没有想它们那样有花括号括起来封闭的作用域。

    接下来你看一个例子就会懂了

    if(true){

            var color = "blue"

           }

    alert(color);           //"blue"

    结果是不是让你大吃一惊,你一定会疑惑为什么if外也可以引用color变量。在for语句中也一样

    for(var i=0;i<10;i++){

    alert(i);           //10

    这2个语句在JS中很特殊,if语句中的变量会将变量添加到当前的执行环境中(也就是和if同一节中),也就是说可以在if同

    阶环境中也可以使用color变量,但到了上一节执行环境中就不能使用color了,因为color在其下一节梯子了。for语句也类似。

    JS中还有一个神奇的地方,就是声明变量。

      使用var声明的变量和普通变量一样,只能在该阶执行环境中或下一阶执行环境中使用,不能在上一阶环境中使用

    例如:

      function add(num1.num2){

          var sum = num1 + num2;

          return sum;

    }

    var result = add(10,20);         //30

    alert(sum);         //由于sum不是有效的变量,因此会导致错误

    然而JS神奇之处就在于 当我们不用var声明一个变量时,该变量会自动被添加到全局变量环境中,也就是最高的那一节梯子中。

    例如:

      function add(num1.num2){

          var sum = num1 + num2;

          return sum;

    }

    var result = add(10,20);         //30

    alert(sum);         //30

    也就是说在我们调用玩add函数时,sum还没有被销毁,依旧保留下来,后面的代码依旧可以访问它。

  • 相关阅读:
    开源框架/软件汇总
    如何查看Maven项目的jar包依赖
    我的前端技术栈(2018版)
    解决在Mac上用pyenv安装python3失败的问题
    学习jenv
    学习sbtenv
    解决MAC下修改系统文件没权限的问题
    学习Spring Boot
    学习音标
    C# 对List中的Object进行排序
  • 原文地址:https://www.cnblogs.com/binguo666/p/7833060.html
Copyright © 2020-2023  润新知