day03
chapter 4
1,ECMAScript中所有函数的参数都是按值传递的。
- function changeStuff(num, obj1, obj2)
- {
- num = num * 10;
- obj1.item = "changed";
- obj2 = {item: "changed"};
- }
- var num = 10;
- var obj1 = new Object();
- obj1.item = "unchanged";
- var obj2 = new Object();
- obj2.item = "unchanged";
- changeStuff(num, obj1, obj2);
- alert(num); //10
- alert(obj1.item); //changed
- alert(obj2.item); //unchanged
2,局部作用域中定义的变量可以在局部环境中与全局变量互相使用。内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。每个环都有可以向上搜索作用域链,以查询变量和函数名。
3,没有块级作用域
4,js具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。对于不再使用的变量,垃圾收集器将给予标记,通常用于标识无用变量的策略有以下两种:
(一)最常用的是垃圾收集方式是标记清除(mark-and-sweep)
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记,而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收所占用的内存空间。
(二)第二种不太常见的策略叫做引用计数(reference counting),它的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。看起来也不错的方式,为什么很少有浏览器采用,还会带来内存泄露问题呢?主要是因为这种方式没办法解决循环引用问题。比如对象A有一个属性指向对象B,而对象B也有有一个属性指向对象A,这样相互引用如下示例:
- function test(){
- var a={};
- var b={};
- a.prop=b;
- b.prop=a;
- }
- window.onload=function outerFunction(){
- var obj = document.getElementById("element");
- obj.onclick=function innerFunction(){};
- };
的变量,自然也包括obj。简单的方式就是手工解除循环引用,如:
- window.onload=function outerFunction(){
- var obj = document.getElementById("element");
- obj.onclick=function innerFunction(){};
- obj=null;
- };
ie6是当环境中存在256个变量、4096个对象、64k的字符串任意一种情况的时候就会触发垃圾回收器工作。ie7中调整为动态修改触发条件。如果垃圾回收器回收的内存分配量低于程序占用内存的15%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,如果回收的内存高于85%,说明大部分内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工作职能了很多。