JS学习笔记整理二 变量、做用域和内存问题

变量、做用域和内存问题

基本类型和引用类型

基本类型和引用类型的区别。对保存对象的变量进行复制,操做的是对象的引用。可是添加对象的属性,操做的就是实际的对象。基本类型没法动态添加属性。这里涉及到昨天说的包装对象的问题。基本类型是存在栈内存中的。引用类型是存在堆内存,其在堆内存的地址存在栈内存。javascript

Ecmascript中全部函数的参数都是按值传递的,而不是引用。即使是做为引用类型的对象,其实也是值传递。虽然在函数内修改对象的属性会反映到实际的对象中。但重写形参,并不会反映到原始的引用。(红皮书71p证实)由于是值传递,形参保存的是对象的引用地址,所以重写形参必然会断开与原始对象的联系。前端

检测类型,以前学到typeof,能够很方便的检测出number,string,boolean,undefined。可是null会检测为object。这是针对基本类型,可是不少时候咱们须要查看的是对象的类型。这时候须要用instanceof操做符。和typeof同样也是关键字哦,因此不须要驼峰写法。java

变量 instanceof 类型    //结果返回布尔值。
复制代码

执行环境及做用域

执行环境也叫执行上下文。每一个执行环境都对应一个变量对象variable object。编程

var color="blue";
function changecolor(color){
    color="orange";
}
changecolor(color);
console.log(color);//blue
 

var color="blue";
function changecolor(){
    color="orange";
}
changecolor();
console.log(color);//orange
复制代码

做用域链永远都是从内而外的搜索,永远都是单向、线性的。浏览器

延长做用域链

with和try-catch能够延长做用域链。框架

function buildUrl(){
    var qs = "?debug=true";
    with(location){
        var url = href + qs;
    }
    return url;
}
console.log(buildUrl());
复制代码

try-catch块中dom

try{
    doSomething();
}catch(ex){
    alert(ex.message); //做用域链在此处改变
}
复制代码

在发生异常进入catch代码段时。异常对象被推入新的变量对象并置于做用域链最前端。而catch代码段内的局部变量则进入到下一个执行环境的变量对象中。所以,catch内的代码量较多时性能会降低。解决的办法就是委托其余函数进行处理。如:函数

try{
    doSomething();
}catch(ex){
    handleError(ex); //做用域链在此处改变
}
复制代码

同时,咱们也经过这个例子了解了,为何常说要少用全局变量。由于全局变量在做用域链的最后,会形成性能问题。性能

有一个技巧,当屡次引用一个全局变量时,咱们能够将其先保存为局部变量,再调用这个局部变量。这也是咱们在一些框架里常常看到的写法。ui

没有块级做用域

使用var声明的变量会自动添加到最接近的环境中。因此在with中建立的变量会加入到其函数环境内。而并不像一些文章说的所谓返回

初始化未声明的变量在严格模式会报错。非严格模式会成为全局变量。

垃圾收集 GC

Javascript有自动垃圾收集机制。

主要的方式是标记清除(mark-and-sweep并列关系)。 当变量进入环境,则标记其“进入环境”,有次标记的变量都是不能释放的。当其离开环境,则标记其“离开环境”。

不常见的方式是引用计数。引用计数存在一些严重的问题,好比循环引用,两个对象互相引用,致使引用计数永远不为0,没法获得回收。在ie9之前,dom-js存在内存泄露的问题就是由循环引用引发的。若是想完全回收对象,则能够断开引用。即将涉及循环引用的变量赋值null,便可消除。

垃圾收集器是周期运行的,所以肯定垃圾收集的时间间隔很是重要。Ie早期是根据内存分配量的一组阈值运行的,当超过期就启动。但若是一个脚本自己就须要那么多,垃圾收集就会频繁触发。Ie7之后变为动态修正阈值。

Javascript有自动垃圾收集机制,通常不用在乎内存分配和回收。可是系统分配给浏览器的资源一般比较少,由于担忧js耗尽全部系统内存致使崩溃。因此在编程时要注意:针对全局变量和全局对象的属性,在不用的时候主动赋值null。以便垃圾收集下一次回收释放内存。函数环境的局部变量执行完毕就会自动解除引用。

给不用的变量或属性主动赋值null,一方面消除循环引用,一方面利于垃圾收集。

红皮书(js高程)82p的总结很精炼,颇有帮助。

相关文章
相关标签/搜索