变量、作用域和内存问题

变量

基本类型 和 引用类型 的值

  • 基本类型有:Undefined, Null, Boolean, Number, String (与java不同,string也是基本类型)
  • 引用类型是指可能由多个值构成的对象
基本类型值和引用类型值的特点:
  • 基本类型值在内存中占据固定大小的空间,因此保存在栈内存中
  • 引用类型的值是对象,保存在堆内存中
  • 包含引用类型的变量实际上包含的并不是对象本身,而是指向该对象的指针
  • 一个变量赋值给另一个变量,如果是基本类型,会创建这个值的副本,如果是引用类型,复制的其实是指针。最终两个变量指向同一个对象。
  1. 引用类型可以添加属性,基本类型不可以。例如:
    1
    2
    3
    var a = "123";
    a.age = 21;
    alert(a.age);//undefined
  1. 函数是按值传递参数的,而非按引用传递参数。(相当于被传递的值会复制给函数的参数,基本类型和引用类型各自的复制不同)
  2. 检测类型
  • typeof 基本类型可以有效的判别基本类型
  • instanceof 来判别某个值是何种对象

执行环境及作用域

  1. 执行环境(作用域)
    • 执行环境分为全局环境和函数执行环境
    • 每次进入新的执行环境,会创建新的作用域链
    • 作用域链中,局部的环境,有权访问父级的作用域,无权访问子级作用域
    • 执行环境有助于确定何时释放内存
  2. 作用域链延长:

    • with语句
    • try-catch语句的catch块
    • catch块中,只对传进来的e特殊处理,在catch声明的变量,依然能在catch外部块访问到,说明他并不是单独的作用域
  3. js 没有块级作用域
    js的作用域是函数级的,没有块级作用域,这点经常会导致理解上的错误。
    例如:

    1
    2
    3
    4
    for(var i = 0 ; i < 10 ; i++){
    doSomeThing();
    }
    alert(i); // 10

变量名i在第四行仍然可以打印出来,是因为,for循环中,并不是独立的作用域。var i , 会被提升到for循环所在的函数。所以i仍然存在

变量名提升:使用var声明的变量会自动被添加到最接近的环境中,而没用var的,则会添加到全局环境中

垃圾回收

  1. 标记清除
    • 离开作用域的值自动被标记为可回收。因此在垃圾收集阶段将被回收
    • 目前主流的收集算法是标记清除
  2. 引用计数
    • 引用计数在循环引用的时候,可能导致内存泄漏
    • 应该在变量不需要用到的时候解除引用,有助于解除循环引用,并且有效的垃圾回收
  3. 管理内存:为了确保占用最少的内存让页面获得更好的性能,则需要解除引用(当变量不在有用,将其置为null);

    注意,解除引用后,并不意味着立即被回收,只有下次垃圾收集器执行的时候,才会真正回收




关于作者:
AndyChen,前端开发,Hybrid App
联系方式:374664805@qq.com
博客:http://chen4342024.github.io/

本文为原创文章,因此转载请保留原出处
本文永久链接:http://chen4342024.github.io/2016/06/10/变量、作用域和内存问题/

坚持原创技术分享,您的支持将鼓励我继续创作!