zoukankan      html  css  js  c++  java
  • javascript变量的作用域

    一、基本类型和引用类型

    • 基本类型值指的是简单的数据段,而引用类型值指的是那个可能多个值组成的对象。
    • 将一个值给变量时,javascript解析器首先要确定是基本类型还是引用类型,基本数据类型可以直接操作保存在变量中的值,而引用数据类型的值是保存在内存中的对象,在操作对象时,实际上操作的是对象的引用而不是实际的对象。

    二、变量的赋值

    • 如果从一个变量上向另一个变量上复制基本数据类型的值,会在变量对象上创建一个新值,然后把该值复制到新变量的位置上, 如下代码:
      var num1 = 5; 
      var num2 = num1;

    • 引用类型,其实同样会将原来变量上的值复制一份到新的变量当中,只不过,复制的其实是原来变量的一个指针,而这个指针指向存储在堆中的一个对象。复制完成后,两个变量都指向了堆中的同一个对象,所以改变其中一个的值,会对另外一个产生影响。如下代码:
      var obj1 = new Object(); 
      var obj2 = obj1; 
      obj1.name = "Nicholas";
      alert(obj2.name);   //"Nicholas" 

      

    三、传递参数

    • 在javascript里面,参数的传递都是按照值类型来传递的,即使你传入的是一个引用类型
      function setName(obj) {
           obj.name = "Nicholas"; 
              }
      var person = new Object(); 
      setName(person);
      alert(person.name);   //"Nicholas"

      上面代码的返回结果貌似参数是引用类型的传递,因为开始person对象没有属性,调用了setName方法之后,给参数obj加上了name参数,然后外面的person打印person.name竟然是有值的,这是很明显的引用传递的效果。但是不要被这种现象所迷惑,javascript在传递引用类型的参数的时候,只要这个参数不发生改变,那么还是按照引用类型来处理,但是只有发生了改变效果就完全不一样了

      function setName(obj) {
           obj.name = "Nicholas";
           obj = new Object();
           obj.name = "Greg";
       } 
      var person = new Object(); 
      setName(person);
       alert(person.name);   //"Nicholas"

      上面的例子可以看出区别,如果真的是引用传递,那么obj重新赋值,并且加上了name参数,最后person打印的应该是Greg的名字,但是结果却是原来的值。

    四、执行环境及作用域

    • 执行环境(execution context)定义了函数或者变量有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之相关联的变量对象,环境中定义的所有的变量和函数都保存在这个对象中
    • 全局执行环境是最外围的执行环境,在web浏览器中,其实就是window对象,因此,所有全局变量和函数,都是作为window的属性和方法创建的,某个执行环境所有代码执行完毕之后,该环境被销毁,保存在其中的变量和函数定义也随之被销毁(全局执行环境直到应用程序退出,及浏览器关闭的时候才会被销毁)
    • 每个函数都有自己的执行环境,当程序执行到一个函数时,函数的环境会被创建出来,进入当前程序的流程,而在函数执行完成之后,程序流程将其弹出并销毁,把控制权返回给之前的执行环境
      • 当代码在一个环境中执行时,会创建变量对象的作用域链,其根本意义就是在不同层级的执行环境中,保证各个执行环境中的变量有序访问,如下代码:
        var color = "blue";
         function changeColor(){ 
            var anotherColor = "red"; 
            function swapColors(){
                 var tempColor = anotherColor;
                 anotherColor = color;
                 color = tempColor;     //在 swapColors函数里面可以访问tempColor,anotherColor和color 
             } 
             // 在这里可以访问anotherColor和color,但不能访问tempColor                   
        swapColors();
        }


        
        

        通过例子,可以看出,内部环境可以通过作用域链访问它之上的所有外部环境,但是外部环境不能访问内部环境中的任何变量和函数。这些环境是线性的,有次序的。

      • 每个环境都可以向上搜索作用域链,以查询变量和函数名;而任何环境都不能通过向下搜索作用域链而进入另一个执行环境
        var color = "blue";
         function getColor(){ 
                return color; 
        } 
        alert(getColor()); //"blue"   

        getColor函数里面的color变量是从里往外搜索到上级外部环境的color得到的。

      • 在搜索的过程中,如果出现同名的局部变量,这个搜索就会停止:
        var color = "blue";
         function getColor(){
             var color = "red"; 
            return color; 
        }
         alert(getColor()); //"red"
  • 相关阅读:
    LeftoverDataException,依赖包,apache license 2.0
    GPL,BSD,Apache,MIT开源许可协议
    一次重构经历
    转载:reactor模式学习
    版本控制学习
    系统开发,出错处理,日志
    最近学习linux命令的一个总结
    sudo,linux 新建账号,并开通ssh登录
    运行R 报错R cannot R_TempDir, 继而发现/dev/mapper/VG00-LV01 磁盘空间已满
    用InputStream读出来转换成String类型
  • 原文地址:https://www.cnblogs.com/5huihui/p/4090428.html
Copyright © 2011-2022 走看看