js中变量、作用域和内存问题

js中变量、作用域和内存问题

基本类型和引用类型的值

​ 基本类型值是简单的数据段,而引用类型值指那些可能由多个值构成的对象。

​ 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中。

​ 引用类型的值是对象,保存在堆内存中。

​ 包含引用类型的值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。

动态的属性

只能给引用类型值动态的添加属性,不能给基本类型的值添加属性

复制变量值

如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。

​ 如果从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。

传递参数

ECMAScript中所有函数的参数都是按值传递的。

检测引用类型

确定一个值是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符。

instanceof操作符

语法:

result=variable instanceof constructor

返回true或false

执行环境及作用域

​ 所有变量都存在于一个执行环境(也称作用域)当中,这个执行环境决定了变量的生命周期,以及哪一部分代码可以访问其中的变量。

​ 执行环境有全局执行环境(也称为全局环境)和函数执行环境之分;

​ 每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;

​ 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;

​ 全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;

​ 变量的执行环境有助于确定何时释放内存。

延长作用域链

在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。

(1)try-catch语句的catch块:会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

(2)with语句:会将指定的对象添加到作用域链中。


function buildUrl(){
    var qs="?debug=true";
with(location){
    var url=href+qs;
}
return url;
}
var buildUrl=buildUrl();
console.log(buildUrl);//file:///D:/project/this.html?debug=true

没有块级作用域

在其他类C的语言中,由花括号封闭的代码块都有自己的作用域(由ECMAScript的话来讲,就是它们自己的执行环境),但在JavaScript中,没有块级作用域。变量声明会被添加到当前的执行环境中。

垃圾回收策略

JavaScript具有自动垃圾收集机制。

标记清除式:当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

​ 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

引用计数式:跟踪记录每个值被引用的次数。当引用类型值的引用次数变成0时,垃圾收集器会释放那些

引用次数为零的值所占用的内存。当代码中出现循环引用现象时,“引用计数”算法就会导致问题。

性能问题

确定垃圾收集的时间间隔是一个非常重要的问题。IE7将触发垃圾收集的变量分配、字面量、或数组元素的临界值调整为动态修正。极大的提升了IE在运行包含大量JavaScript的页面时的性能。

管理内存

即优化内存占用。最佳方式:解除引用——一旦数据不再有用,最好通过将其值设置为null来释放其引用。

猜你喜欢

转载自blog.csdn.net/yangyuqingabc/article/details/82726308
今日推荐