变量、作用域和内存问题
- 基本类型和引用类型的值
(1)基本类型:按值访问(Undefined、Null、Boolean、Number、String)
(2)引用类型:按引用访问
基本类型 |
引用类型 |
|
动态属性 |
不能给基本类型的值添加属性 |
动态的添加、改变、删除属性和方法 |
复制变量值 |
在变量对象上创建一个新值,然后将该值复制到新变量分配的位置上(互不影响) |
复制结束两个变量引用一个对象(互相关联) |
传递参数 |
把函数外部的值复制给函数内部的参数 |
把这个值的内存地址复制给另一个局部变量 |
检测类型 |
使用typeof 检测基本类型,如果是null或对象,会返回“object”====返回的是string类型 |
使用instanceof 检测具体的类型:对象、数组或者正则等。语法:result = variable instanceof constructor。 |
- 执行环境及作用域
执行环境定义了变量或函数有权访问其他数据,决定了它们各自的行为;都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
代码在一个环境中执行时,会创建变量对象的作用域链,保证对执行环境有权访问的所有变量和函数的有序访问。
内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。环境之间的联系是线性有次序的,只可以向上搜索作用域链,以查询变量和函数名;下级的作用域链中包含的对象:自己的变量对象和上级的变量对象,直到全局变量对象。
标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程从更作用域链的前端开始,然后逐级地向后回溯,知道找到标识符位置,若找不到,会导致错误。
延长作用域链
执行环境的类型:全局和局部;
延长作用域链:有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。在下列两种语句会加长作用域链:
- try-catch语句的catch块(创建一个新的变量对象,包含抛出的错误对象声明)
- with语句(将指定对象添加到作用域链中)
没有块级作用域
变量是被添加到当前的执行环境中的,
使用var声明的变量会被自动添加到最近的环境中,在函数内部,最近的是函数的局部环境;with语句中,最接近的是函数环境,没有使用var初始化的,会自动添加到全局环境(不建议这样使用,严格模式下,初始化未经声明的变量会导致错误)。
查询标识符
标识符(变量名):查询时,先在局部环境中查找,没找到则继续向上搜索,一直到全局环境的变量对象,若还没找到,则是该变量尚未声明。若找到,则停止搜索,不在进入下一个变量对象。(局部环境有,则不使用父级的标识符)
- 垃圾收集
JavaScript具有自动垃圾收集机制。
标记清除(最常用的垃圾收集方式)
可以用任何方式来标记变量
引用计数
跟踪记录每一个值被引用的次数。代码存在循环引用现象时,不适用。