javascript高级程序设计笔记(三)

来源:互联网 发布:什么是oracle元数据 编辑:程序博客网 时间:2024/05/22 00:12
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); //10alert(obj1.item); //changedalert(obj2.item); //unchanged
obj1传入函数 changeStuff 时,changeStuff函数内部变量 obj1是一个新的内存变量,只是期指向旧的对象值,所以改变对象中item的值会在函数外部表现出来。obj2传入函数 changeStuff1时,changeStuff函数内部变量 obj2是一个新的内存变量,依旧期指向旧的对象值,但在函数内部又给内部的obj2变量重新赋值,使其指向一个新的对象,所以改变对象中item的值不会影响函数外部的obj2对象。

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;        }
这样a和b的引用次数都是2,即使在test()执行完成后,两个对象都已经离开环境,在标记清除的策略下是没有问题的,离开环境的就被清除,但是在引用计数策略下不行,因为这两个对象的引用次数仍然是2,不会变成0,所以其占用空间不会被清理,如果这个函数被多次调用,这样就会不断地有空间不会被回收,造成内存泄露。在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,也就是说只要涉及BOM及DOM就会出现循环引用问题。如下例:
window.onload=function outerFunction(){        var obj = document.getElementById("element");        obj.onclick=function innerFunction(){};    };
obj引用了document.getElementById("element"),而document.getElementById("element")的onclick方法会引用外部环境中
的变量,自然也包括obj。简单的方式就是手工解除循环引用,如:
window.onload=function outerFunction(){        var obj = document.getElementById("element");        obj.onclick=function innerFunction(){};obj=null;    };
什么时候触发垃圾回收
    ie6是当环境中存在256个变量、4096个对象、64k的字符串任意一种情况的时候就会触发垃圾回收器工作。ie7中调整为动态修改触发条件。如果垃圾回收器回收的内存分配量低于程序占用内存的15%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,如果回收的内存高于85%,说明大部分内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工作职能了很多。

0 0
原创粉丝点击