第四章 变量、作用域和内存问题
4.1 基本类型和引用类型的值
-
-
引用类型值指可能由多个值构成的对象。
-
基本类型不能添加属性,引用类型指可以动态地添加属性。
-
复制变量值
-
- 基本类型中,复制后是两个变量是完全独立地,只是被复制变量地一个副本,操作没有影响;
- 引用类型中,复制地是同样是被复制变量地值,但这个值的副本实际上是一个指针,指向内存堆中的一个对象,复制后,两个变量实际指向同一个对象,会相互影响;
-
传递参数 所有函数的参数都是按值传递
-
- 基本类型的参数,是传入外部的值的副本传入参数,所以互不影响;
- 引用类型的参数,传入的是指针(地址值),所以参数改变属性时,会影响外部变量,而当函数内参数重新赋值一个新对象时,参数就会指向新的指针(地址值),而后续改变也是改变该新对象,而外部变量依然指向原本的对象,所以外部变量不会有改变;
-
person instanceof Object/Array/RegExp 可检测引用类型 (Object 均返回 true,因为时所有引用类型值的实例)
-
作用域链,使保证对执行环境的有序访问,从内到外。
-
没有块级作用域
-
- for/if 花括号中的变量可全局使用,但具有函数作用域,函数作用域中的变量若不用 var 定义,直接使用,则会被自动添加到全局环境中。
- 查询标识符,从作用域链前端开始,逐渐向上级查询,直到查询到或没有该标识符。
-
共享传递:传引用的拷贝。
变量 obj1 把它里面的值传递(复制)给了参数 obj,让这个参数也指向原对象。因此如果在函数内部给这个参数 obj 赋值另一个对象时,这个参数就会更改它的值为新对象的内存地址指向新的对象,但此时原来的变量仍然指向原来的对象,这时候他们是相互独立的;但如果这个参数是改变对象内部的属性的话,这个改变会体现在外部,因为他们共同指向的这个对象被修改了!
setName()中的 obj1 是一个引用,他的内容是某块内存的地址,这个地址的值来自于外部定义的内存,是 obj 对象在内存中地址的一份拷贝,同时,在函数内部这个参数的值是可以直接被修改的,可以指向其他对象,但是 obj 是不会随着 obj1 的修改而指向其他对象的。
4.3 垃圾收集
-
- 标记清除,开始时所有对象都被进行标记,然后遍历正在使用的对象,及这些对象所引用的其它对象,然后去除标记,而剩下的就是没有在使用的对象,可以进行垃圾回收
-
可以理解为内存为大海,每个对象是一个岛屿,通过大桥连接,现在要找出与大陆连接的岛屿,没有标记到的就是孤岛,即使两个岛屿相连那也是孤岛,可以进行回收;
-
- 引用计数(相互引用)。
- 管理内存,解除引用 object = null;