zoukankan      html  css  js  c++  java
  • 变量、作用域和内存问题

    //JavaScript高级程序设计读书笔记

    1,基本类型和引用类型的值

            基本类型值:简单的数据段。有5种基本数据类型,Undefined,Null,Boolean,Number和String;它们的值保存在栈内存。基本类型是按值访问的,所以我们操作的是保存在变量中的实际值。

            引用类型值:JavaScript不能直接操作对象的内存空间,实际上是操作对象的引用,而不是实际的对象。引用类型的值是按引用访问的。查询引用类型的变量时,先从栈内存读取内存地址,然后根据地址找到堆内存中的值。

       1.1  动态的属性

          引用类型值的属性和方法可以修改:       

    var persion = new Object();
    persion.name="Nicholas";
    alert(persion.name);    //"Nicholas"

            基本类型值不能添加属性和方法:    

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

        1.2  复制变量值 

            基本类型:一个变量向另一个变量复制,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上,两个变量互不影响。

            引用类型:同样会将存储在栈中的值复制一份到为新变量分配的空间中。不同的是这个值实际上就是一个指针,指针指向的是堆内存中的一个对象,两个变量实际上指的是同一个对象,改变其中的一个变量就会影响另一个。

        1.3  传递参数

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

            //基本类型是按值传递的。

    function add(num){
       num +=10;
       return num;
    }
    var count = 20;
    var result = add(count);
    alert(count);   //20没有变化
    alert(result);   // 30

                   //引用类型也是按值传递的,这个值是对象在内存中的地址值。    

    function setName(obj){
       obj.name="Bob";
       obj = new Object();   //重新定义了一个对象,obj的值改变,obj指向一个新的对象。
       obj.name = "Greg";    //为该对象定义了一个不同值得name属性。此时和persion不是
                               同一个对象
    }
    var persion = new Object();
    setName(persion);  //persion和obj指向同一个对象,
    alert(persion.name); //  "Bob"

            1.4  检测类型

                typeof 操作符,确定一个变量是string,number,boolan,还是undefined。如果是对象或者null返回object;如果是函数返回function。

                var s = "Hellow World";

                console.log(typeof s);  //string 

        instanceof操作符,确定一个变量是什么类型的对象。如果检测基本类型值,返回false   

    var arr =[1,2,3];
    console.log(arr instanceof Array);//true

    2,执行环境及作用域

        执行环境定义了变量或函数有权访问的其他数据。每个环境都有与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。//全局环境被认为是window对象,所有的全局变量和函数都作为window对象的属性和方法创建的。    

       // 函数的环境在函数执行之后,栈将其环境弹出,

    内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。每个环境都可以向上搜索作用域链,任何环境都不能向下搜索作用域链而进入另一个执行环境。

       2.1  延长作用域链

    //try-catch  语句  和 with 语句,这两个语句都会在作用域链的前端添加一个变量对象。使作用域链得到加长。with语句将指定对象添加到作用域链中,catch会创建一个新的变量对象。

    function buildUrl() {
       var qs = "?debug=true";
       with(location) {   //with将location对象放添加到作用域链中,
                              //当前环境可以访问location中的变量和方法
           var url = href + qs;
       }
       return url;
    }
       console.log(buildUrl());

        2.2 没有块级作用域

        

    if (true) {//if语句中的变量声明会将变量添加到当前的执行环境
       var color = "blue";
    }
    console.log(color); //"blue"
    for (var i =0; i< 10 ; i++) {
       var s = i; //即使for循环结束后,也依旧会存在于循环外部的执行环境中。
    }
    console.log("s的值为"+s); //s的值为9
    console.log("i的值为"+i);//i的值为10

    function add(num1,num2) {
       var sum = num1+num2;
       return sum;
    }
    var result = add(10,20); //30
    console.log(sum); //由于sum不是有效变量,会报错。sum is not defined

    //初始化赋值时没有使用var关键字,会将变量添加到全局环境中

    function add1(sum1, sum2) {
       he = sum1 + sum2;//初始化时没有使用var关键字,he成为全局变量。
       return he;//在严格模式下,初始化未经声明的变量会导致错误。
       //不声明而直接初始化也可能导致意外,一定要先声明在使用。
    }
    var result1 = add1(10, 20);//30
    console.log(he); //30

    3,垃圾收集

        js有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。原理:找到不再继续使用的变量,然后释放其占用的内存。垃圾收集器会按照固定的时间间隔,周期性的执行这一操作。

    标记清除:垃圾收集器在运行的时候会给存储在内存中的每个变量都加上标记,然后去掉环境中的变量和被环境中变量引用的变量的标记,销毁那些仍带有标记的值并回收他们所占用的内存空间。

    引用计数:跟踪记录每个值被引用的次数。垃圾收集器运行时会释放那些引用次数为0的值所占用的内存。

    4,管理内存

        确保占用最少的内存可以让页面获得更好的性能,而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用。解除引用这一做法适用于大多数全局变量和全局对象的属性。局部变量会在他们离开执行环境时被自动解除引用。

    function createPerson(name) {
       var localPerson = new Object();
       localPerson.name=name;
       return localPerson;
    }
    var globalPerson =createPerson("Bob");
    //手动解除globalPerson的引用
    globalPerson=null;
  • 相关阅读:
    41 最大子数组
    4 丑数 Ⅱ-找出第n个丑数
    写在编程初始
    lightoj 1068
    2018-11-8-内置函数(2)
    2018-11-7-内置函数(1)
    2018.11.06 生成器函数进阶&列表推导式&生成器表达式
    python2&python3的区别
    第一次打开Pycharm如何操作?
    关于做题的一些反思
  • 原文地址:https://www.cnblogs.com/niusan/p/6696781.html
Copyright © 2011-2022 走看看