本文内容
- 基本类型和引用类型的值
- 执行环境
- 垃圾收集
ECMAScript的变量有两种不同类型的值:基本类型和引用类型。
在将一个值赋值给变量时,解析器必须确定这个值是基本类型还是引用类型值。
复制变量值
复制基本类型的值,会创建一个新值,然后把该值复制到位新变量分配的位置上。复制后,两个变量之间是完全独立的。
复制引用类型的值,也会将存储在变量对象值的值复制一份到为新变量分配的空间中,不同的是,这个值实际上是一个指针(地址,引用),这个指针指向存储在堆中的一个对象。复制后,两个变量实际上将引用同一个对象。改变其中一个变量,就会影响另外一个变量(相互影响)。
传递参数
ECMAScript中所有函数的参数都是按值传递的。即把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
基本类型值的传递就如同基本类型变量的复制一样,引用类型值的传递就如同引用类型变量的复制一样。
执行上下文及作用域
执行环境决定了变量或函数有权访问的其他数据,决定了它们各自的行为,现在更多的讲的是执行上下文。
每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。我们编写的代码无法访问这个对象,但是解析器在处理数据时会在后台中使用它。
每个函数都有自己的执行环境。当执行流进去一个函数时,函数的环境就会被推入一个环境栈中,在函数执行之后,栈将其执行环境弹出,把控制权返回之前的执行环境。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。
作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。
执行环境的类型总共有两种——全局和局部(函数)。
变量声明
使用var的函数作用域声明:
在使用var声明变量时,变量会被自动添加到最接近的上下文。
var声明会被拿到函数或全局作用域的顶部,位于作用域中所有代码之前,这个现象叫做“提升”。
使用let的块级作用域声明:
let与var的另一个不同之处是在同一作用域内不能声明两次。
重复的var声明会被忽略,而重复的let声明会抛出错误。
使用const的常量声明:
使用const声明的变量必须同时初始化为某个值,声明后,在其生命周期的任何时候都不能再重新赋予新值。
垃圾回收
JavaScript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存,所需内存的分配以及无用内存的回收实现了自动管理。
性能
垃圾回收程序会周期性的运行,如果内存中分配了很多变量,则可能造成性能损失,因此垃圾回收的时间调度很重要。
内存管理
解除引用:如果数据不再必要,那么把它设置为null,从而释放其引用。
这个建议最适合全局变量和全局对象的属性。局部变量在超出作用域后会自动解除引用。
内存泄漏
JavaScript中的内存泄漏大部分是由不合理的引用导致的。