闭包、作用域和内存

来源:互联网 发布:迅雷快鸟mac版 编辑:程序博客网 时间:2024/05/16 05:21

《高性能JavaScript》

闭包是JavaScript最强大的特性之一,它允许函数访问局部作用域之外的数据。闭包的使用通过DouglasCrockford的多篇文章的介绍而流行开来,如今普遍应用在复杂的web应用中,然而使用闭包可能会导致性能问题。

思考以下的代码

function assignEvents(){     var id = "xdi9592";     document.getElementById("save-btn").onclick=function(event){     saveDocument(id);     }}

assignEvents()函數在給一个DOM设置事件处理函数。这个事件处理函数就是一个闭包,它在assignEvents()执行时创建,并且能否访问所属作用域的id变量。为了让这个闭包访问id,必须创建一个特定的作用域链。

assignEvents()函数 执行时,一个包含了变量id以及其他数据的活动对象被创建。它成为执行环境作用域链中的第一个对象,而全局对象紧随其后。当闭包被创建时,它的[[Scope]]属性被初始化为这些对象。

由于闭包的[[Scope]]属性包含了与执行环境作用域链相同的对象的引用,因此会产生副作用。通常来说,函数的活动对象会随着执行环境一同被销毁。但引入闭包时,由于引用仍然存在于闭包的[[Scope]]属性中,因此激活对象无法被销毁。这意味着脚本中闭包与非闭包函数相比,需要更多的内存开销。在大型Web应用中,这可能是个问题,尤其在IE浏览器需要关注。由于IE使用非原生JavaScript对象来实现DOM对象,因此闭包会导致内存泄漏。

当闭包函数代码执行时,会创建一个执行环境,它的作用域链与属性[[Scope]]中所引用的两个相同的作用域链对象一起被初始化,然后一个活动对象为闭包自身创建。

注意在闭包中用到的两个标识符,idsaveDocument,它们的位置在作用域链第一个对象之后,这就是使用闭包最需要关注的性能点:在频繁访问跨作用域的标识符时,每次都会带来性能损失。

在脚本编程中,最好小心地使用闭包,它同时关系到内存和执行速度。

0 0
原创粉丝点击