• 第四章 变量 作用域和内存问题


    4.1变量

    变量包含2种类型的值:

    基本类型的值: 即undefined,null, string,number,boolean.   按值访问,可以操作保存在变量中实际的值, 不能添加属性。

    var name = "Nicholas";
    name.age = 27;
    console.log(name.age);
    //undefined

    引用类型的值:多个值构成的对象。JS不允许直接操作对象的内存空间。给一个对象添加属性,是在实际的对象中添加。

     

    俩种类型值的区别: 

    1.保存方式不同: 基本类型保存在对象空间中。引用类型保存在内存中。 

    2.复制变量值时:基本类型 从一个变量复制到另外一个变量,变量创建一个副本,然后把值复制给新变量。

                              引用类型 复制值的一个指针,存储在新变量中,实际引用的是同一个对象。

    var obj1 = new Object();
    var obj2 = obj1;
    obj1.name = "Nicholas";
    console.log(obj1);
    console.log(obj2);
    
    //Object {name: "Nicholas"}
    //Object {name: "Nicholas"}

    传递参数

    JS中所有函数的参数都是按值传递的。

    基本类型的值从一个变量复制到另一个变量,实际是值被复制了俩份。

    function addTen (num) {
       num +=10;
       return num;
     }
    var count = 20;
    var rezult = addTen(count);
    console.log(rezult);
    console.log(count);
    // 30  rezult保存的值 被当做参数传递进addTen进行了+10;再返回
    // 20  count在外部,没有受到+10的影响,所以返回20.俩个值互相独立,互不影响。

    而参数是对象(对象是引用类型的一种)时,也是按值传递。

    function setName (obj) {
       obj.name = "Nicholas";
       obj = new Object();
       obj.name = "Gray";
      }
    var person = new Object();
    setName(person);
    console.log(person.name);
    // Nicholas  即使再函数内部修改了参数的值,原始的引用仍然保持不变。
    // 再函数内部重写obj时,这个变量引用的是一个局部对象,这个局部对象会在函数执行完毕后立即被销毁。

    检测类型

    instanceof:  变量是给定类型的实例返回true.

    function setName (obj) {
       obj.name = "Nicholas";
      }
    var person = new Object();
    setName(person);
    
    console.log(person instanceof Object);
    //true person是Object的实例

    执行环境及作用域

    执行环境:       定义变量或函数有权访问的其他数据,决定他们各自的行为。执行环境中的代码执行完毕后,该环境被销毁,变量和函数也被销毁。

    变量对象:       每个执行环境有一个变量对象。环境中定义的所有变量和函数都保存再这个对象中。

    全局执行环境: 最外围的一个执行环境,也被认为是window对象。所有全局变量和函数都是作为window对象的属性和方法创建的。

    作用域链:       函数有自己的执行环境。代码在一个环境中执行时,会创建变量对象的一个作用域链。用途是搜索变量和函数。作用域链的前端始终都是当前执行代码所在环境的变量对象。

     

    var color = "blue";
    function changeColor() {
        if(color === "blue") {
            color = "red";
          } else {
              color = "blue";
            }
         }
    changeColor();
    console.log("Color is now " + color);           
    // Color is now red

    函数changeColor的作用域链包含2个对象,它自己的变量对象(arguments对象)和全局变量对象(color)。

    var color = "blue";
     
    function changeColor() {
       var anotherColor = "red";
       
       function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        }
    }

    内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境的变量和函数。

    没有块级作用域

    再JS中,if语句中变量声明会将变量添加到当前的执行环境。

    if(true) {
      color = "red";
    }
    console.log(color);
    //red

    for语句创建的变量i既然再for循环执行结束后,依旧存在循环外部的执行环境中。

    for(var i=0; i <10; i++) {
            i++;
        }
    console.log(i);
    //10

    查询标识符

    查询标识符从作用域最前端开始,向上逐级查找与给定名字匹配的标识符。找到为止,没有找到意味着该变量未声明。

    var color = "blue";
    
    function getColor() {
        return color;                //首先在getcolor函数里寻找color标识符,未找到
                                     //接着向上查找,包裹getColor的是全局执行环境,最后在全局执行环境中到了,,并立即返回
      } 
    
    console.log(getColor());
    // blue

     如果存在同名标识符,局部变量优先级最高。

    var color = "blue";
    
    function getColor() {
        var color = "red";      //局部变量覆盖了全局变量
        return color; 
    
      }
    
    console.log(getColor());
    //red
  • 相关阅读:
    Rolling Hash(Rabin-Karp算法)匹配字符串
    vim下单行长文本的时候卡顿解决办法
    设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
  • 原文地址:https://www.cnblogs.com/zhangbaihua/p/5557110.html
Copyright © 2020-2023  润新知