02.第4章:变量、作用域和内存问题

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

  • 基本类型:Undefined、Null、Boolean、Number和String,按值访问,可以操作保存在变量中实际的值。
    基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中。
  • 引用类型:值是保存在内存中的对象。Object
    引用类型的值是对象,保存在堆内存中。

1) 为变量赋值

  • 基本类型


    02.第4章:变量、作用域和内存问题_第1张图片
  • 引用类型


    02.第4章:变量、作用域和内存问题_第2张图片

2)传递参数

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

  • 传递基本类型时,被传递的值会被赋值给一个局部变量(arguments对象中的一个元素)。

在调用addTen(count)方法时,只是把数字20赋值给了局部变量参数num,所以改变的是局部变量num的值。

  • 传递引用类型的值时,把这个值在内存中的地址复制给局部变量。


    02.第4章:变量、作用域和内存问题_第3张图片

    调用setname(person)方法时,将地址赋值给变量obj,obj和person指向同一个对象。


    02.第4章:变量、作用域和内存问题_第4张图片

    并不是传递的引用,如下例子就可以看出来
    02.第4章:变量、作用域和内存问题_第5张图片

3)检测类型

  • typeof


    02.第4章:变量、作用域和内存问题_第6张图片
  • instanceof
    如果变量是给定引用类型的实例,那么返回true


2.执行环境和作用域

02.第4章:变量、作用域和内存问题_第7张图片

分析如上代码,包括3个执行环境:
全局环境window:包含一个变量color,一个函数changeColor()。
changeColor()局部环境:包括变量anotherColor,函数swapColors()。
swapColors()局部环境:一个变量tempColor


02.第4章:变量、作用域和内存问题_第8张图片
作用域链

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

1)延长作用域链

try-catch语句的catch块
with语句


02.第4章:变量、作用域和内存问题_第9张图片

with语句接收的是location对象,因此其变量对象中就包含了location对象所有属性和方法,而将这个变量对象被添加到了作用域链的前端。

2)没有块级作用域(重要)

其他语言中,由{}封闭的代码都有自己的作用域,在执行结束后作用域中的变量会被销毁,但是在JavaScript中,没有块级作用域。


02.第4章:变量、作用域和内存问题_第10张图片

在其他语言中,变量color是if语句的局部变量,执行}结束后,变量color将被销毁。
但是在JavaScript中,在if语句声明的变量color会直接被添加到当前的执行环境,这里是全局环境,可以打印出color值为blue。


02.第4章:变量、作用域和内存问题_第11张图片

执行结束后,i并没有被销毁,而是变成了当前执行环境中的变量,i已经等于10了。
  • 声明变量
    使用var声明的变量会自动被添加到最接近的环境中。
    函数内部:函数的局部环境
    with语句:函数环境
    没有使用var:全局环境
02.第4章:变量、作用域和内存问题_第12张图片
局部变量sum

02.第4章:变量、作用域和内存问题_第13张图片
全局变量sum
  • 查询标识符


    02.第4章:变量、作用域和内存问题_第14张图片

    02.第4章:变量、作用域和内存问题_第15张图片

    搜索过程中,如果存在局部变量的定义,则搜索会自动停止,不再进入另一个变量对象。


    02.第4章:变量、作用域和内存问题_第16张图片

    搜索时首先从局部环境开始,发现了名为color的变量,其值为red。变量找到搜索停止。return的是局部变量。

3.垃圾收集

JavaScript具有自动垃圾收集机制,开发人员不用关心内存使用问题,所需的内存分配和无用的内存回收实现了自动管理。

  • 标记清除(常见的垃圾收集策略)
    垃圾收集器在运行的时候给存储在内存中的所有变量都加上标记,
    然后,他会去掉环境中的变量和被环境中的变量引用的变量的标记,
    在此之后剩下被标记的变量将被视为准备删除的变量
    最后,垃圾收集器完成内存清除工作。
  • 引用计数(不常见的垃圾手机策略)
    引用计数的含义是跟踪记录每个值被引用的次数。
    当声明了一个变量并将一个引用类型值赋值给该变量,则这个值的引用次数+1。
    如果同一个值又被赋值给另一个变量,则引用次数再+1。
    如果包含对这个值引用的变量被赋值了另一个引用,则该值的引用次数-1。
    当这个值的引用次数为0时,说明没有变量指向这个值,没有办法访问。因而就可以清除这些内存。
  • 管理内存
    优化内存占用最佳方式:一旦数据不再有用,将其值设置为null来释放其引用(解除引用),这一般用于全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用。


    02.第4章:变量、作用域和内存问题_第17张图片

你可能感兴趣的:(02.第4章:变量、作用域和内存问题)