999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

JavaScript閉包技術及IE內存泄漏分析

2008-12-31 00:00:00張云帆
電腦知識與技術 2008年35期

摘要:該文主要對Web前端開發中經常使用的瀏覽器端腳本語言JavaScript進行分析,討論了其中閉包技術的使用,并結合IE瀏覽器中內存占用情況分析了不當使用閉包技術造成的內存泄漏情況及避免方法。

關鍵詞:JavaScript;閉包;IE瀏覽器;內存泄漏

中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2008)35-2134-03

Closure in JavaScript Analyze of Memory Leak in IE

ZHANG Yun-fan

(Tongji University, Shanghai 201804, China)

Abstract: This essay mainly researched the Web browser script JavaScript which is widely used in Web development and analyzed the usage of Closure technique. It also researched memory leak and its settlement in Internet Explorer according to memory occupancy rate caused by improper usage of Closure.

Key words: javascript; closure; internet explorer; memory leak

1 JavaScript及DOM文檔模型概述

1.1 JavaScript概述

JavaScript是NetSpace公司引入Java概念所創造的一門語言。最初創建時是為了動態的修改頁面標記,但隨著文檔對象模型(Document object Model,DOM)的出現,以及國際互聯網聯盟(W3C)完成對DOM的標準化,歐洲計算機制造協會(ECMA)也將JavaScript納入ECMAScript規約。

JavaScript是一種解釋型語言,它以程序段的形式包含在html代碼中,當用戶發送請求時,服務器不會對JavaScript進行編譯而是直接將其發送到客戶端,由瀏覽器解釋,因此JavaScript面臨著面對不同瀏覽器的兼容性問題。

JavaScript是一種基于對象的語言而不是面向對象的,由于它支持一定的面向對象技術,所以很多組織和個人利用此開發出了很多框架和工具,使得JavaScript更加具有面向對象的能力。其中閉包就是在實現這些功能時必須要用到的重要特性。

1.2 文檔對象模型(DOM)概述

1.2.1 DOM模型

文檔對象模型(Document object Model,DOM)是提供對文檔內容、結構、風格進行訪問和更新的應用程序接口(API),它是由W3C制定的標準,是一個能讓程序和腳本動態訪問和更新文檔的語言平臺。DOM可以分為3個部分:核心、XML和HTML。DOM和 JavaScript沒有直接關系,其他語言也可以使用DOM。但是由于DOM的出現,JavaScript成為了一種非常強有力的頁面工具。HTML DOM將整個html文檔表述成頁面里的一個樹型結構,其根節點是Document對象,每個元素和屬性都是樹上的一個節點。比如如下一段簡單的html代碼,將其表示成HTML DOM的樹型結構就如圖1所示。

<html>

<head>

<title>你好</title>

</head>

<body>

<h1>標題</h1>

<p>段落</p>

</body>

</html>

1.2.2 使用JavaScript操作HTML DOM

JavaScript可以遍歷DOM文檔樹上的任何節點,動態添加或者刪除節點,也可以對節點的屬性進行修改或對該節點存值進行修改。JavaScript的操作會立即作用的DOM樹上。DOM的部分常見對象如下:

1) Document對象:

Document 對象代表整個 HTML 文檔,可用來訪問頁面中的所有元素。Document 對象是 Window 對象的一個部分,可通過 window.document 屬性來訪問。

2) Event對象:

Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。事件通常與函數結合使用,函數不會在事件發生前被執行。

3) Windows對象

Window 對象是 JavaScript 層級中的頂層對象。Window 對象代表一個瀏覽器窗口或一個框架。Window 對象會在 <body> 或 <frameset> 每次出現時被自動創建。

2 JavaScript中的閉包

2.1 閉包的概念

2.1.1 ECMAJavaScript的垃圾收集

ECMAJavaScript 要求使用自動垃圾收集機制。但是規范沒用規定如何實現,所以不同的瀏覽器實現方式不一樣。一般的思想就是模仿JAVA語言,即如果對象不再“可引用(由于不存在對它的引用,使執行代碼無法再訪問到它)”時,該對象就成為垃圾收集的目標。因而,在將來的某個時刻會將這個對象銷毀并將它所占用的一切資源釋放,以便操作系統重新利用。同時,若只有兩個相互引用的對象,他們不會被第三者引用的話,這兩個對象也會被回收。反言之,如果某對象被其他對象引用,引用者又被引用,只要該引用鏈不形成循環,那么只要最初的引用調用者的生命周期不結束,那么整條鏈上的變量的生命周期都不會結束。

正常情況下,一個函數的生命周期結束時就會滿足垃圾收集條件。此時,作用域中的對象,都不再“可引用”,因此將成為垃圾收集的目標。 然而由于不同瀏覽器的實現不同,在IE瀏覽器中對垃圾收集出現了一些問題,如果使用閉包不當,在一些特殊情況下,將會引起內存的泄漏。

2.1.2 閉包的構造

所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。

這段話是官方的定義,但是卻比較艱澀。下面通過一個簡單的例子可以說明如何構建一個閉包:

<script type=\"text/javascript\">

function test(num) {

var sum =100;

/* function Alert(){alert(sum);} */

var Alert = function() { sum = sum + num; alert(sum); }

return Alert;

}

var fun =test(6);

fun();

</script>

這個程序的運行結果是106。

可以看到在函數test里創建了一個內部的匿名函數函數,并用一個變量Alert指向了該匿名函數。該匿名函數也可按注釋中的構建,效果是同樣的。這樣可以看的比較清晰,一個閉包的構成是通過在對一個函數調用的執行環境中返回一個函數對象構成的。比如,在對函數調用的過程中,將一個對內部函數對象的引用指定給另一個對象的屬性。或者,直接將這樣一個(內部)函數對象的引用指定給一個全局變量、或者一個全局性對象的屬性,或者一個作為參數以引用方式傳遞給外部函數的對象。結合垃圾收集機制來看,一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區,更加通俗的講就是方法內部變量的生命周期超過了方法本身的生命周期。

2.2 閉包的應用

從前面的例子可以看出,閉包主要有2個方面的作用:

第一,在內存里保存一個變量。如上例的變量sum和num,由于fun是test函數內部函數Alert的引用,所以根據垃圾回收原則,Alert函數將不被回收,它所引用的sum和num變量也不被回收,他們將一直存在于內存中。

第二,保護函數內部變量。如上例中的sum變量,它只能被Alert函數訪問,提高了安全性。

下面舉例說明閉包的實際應用。

一個常見的例子是使用setTimout函數來延時執行某些函數。setTimout函數的第一個參數是要執行的函數,第二個參數是間隔時間。可以傳遞給第一個參數一個函數的引用,但是無法同時傳遞該函數的參數。這個問題可以用閉包來解決。例子的代碼如下:

function call (A, B, C){

return (function(){

//以下是對參數的一些操作

A=B+C;

});

}

...

var fun= call (1, 2, 3);

main=setTimeout(fun, 500);

call函數構造了一個閉包,fun是對call函數內部匿名函數的引用,根據垃圾回收機制,call函數內的該匿名函數和它所引用的變量A,B,C都不會被回收,也就是說參數A,B,C的值都一直存在于內存里。后面setTimeout函數使用引用fun的時候,前面fun所指向函數的外部函數call的參數值就得以保存。

閉包機制還可以用來封裝功能。當一個函數要使用其他函數,而其他函數并不會被其他代碼直接調用,那么可以使用閉包技術將其他函數放到函數內部封裝起來,對外使用公共的接口,這樣可以提高代碼的可移植性。

3 不當使用閉包帶來的內存泄漏問題及解決方案

3.1 Internet Explorer 的內存泄漏問題

Internet Explorer 瀏覽器的垃圾收集系統中存在一個問題,即如果 ECMAJavaScript 和某些宿主對象構成了 \"循環引用\",那么這些對象將不會被當作垃圾收集。此時所謂的宿主對象指的是任何 DOM 節點和 ActiveX 對象。循環引用是指當兩個或多個對象以首尾相連的方式相互引用。按照垃圾回收機制,循環引用的對象應當被收集處理。但是,在 Internet Explorer 中,如果循環引用中的任何對象是 DOM 節點或者 ActiveX 對象,垃圾收集系統則不會發現它們與外界對象是隔離的。它們就一直保存在內存里,直至瀏覽器關閉。

3.2 閉包函數引起的循環引用及解決方案

從前面可以知道循環引用是造成內存泄漏的原因,而閉包的使用十分容易造成循環引用,因此可以說閉包的使用是web開發中造成內存泄漏的重要原因之一。IE瀏覽器的COM組件產生的對象實例和網頁腳本引擎產生的對象實例相互引用,就會造成內存泄漏。見圖2。

圖3.1所示,腳本對象和DOM對象形成了循環引用。下面的一段代碼展示了web開發中如何通過閉包造成內存泄漏。

<html>

<script language=\"JavaScript\">

function closureTest (){

var TestDiv = document.createElement(\"div\");

TestDiv.id = \"LeakedDiv\";

TestDiv.onclick = function(){TestDiv.style.backgroundColor = \"red\"; };

document.body.appendChild(TestDiv);

}

</script>

<body onload=\"closureTest()\">

</body>

</html>

可以看到closureTest方法里創建了一個內部匿名函數,由于創建的div塊的一個onclick屬性引用了該匿名函數,該div塊是一個外部對象,所以該匿名函數得以在內存里保留,它所要使用的TestDiv對象也就一直存于內存中,形成了內存泄漏。

如何解決這個問題呢,一個比較好的辦法是在body標簽里添加onunload事件的處理函數,讓它來將形成循環的div塊的屬性置空。代碼如下:

<html>

<script language=\"JavaScript\">

function closureTest (){

//代碼略

}

function BreakLeak() {

document.getElementById(\"LeakedDiv\").onclick = 1;

}

</script>

<body onload=\"closureTest()\" onunload=\"BreakLeak()\">

</body>

</html>

這樣,onclick屬性就不會再引用匿名函數,循環引用也就中斷,TestDiv對象將會最終被進行垃圾回收。

4 總結

Web開發使用廣泛,其中尤以JavaScript為最常用的瀏覽器端腳本語言。許多程序員使用大量JavaScript高級技巧或者使用流行的庫,如JQuery,Prototpye,Dojo等。這些應用大多涉及到閉包技術,使用閉包技術能都讓JavaScript實現許多強大的功能。但如果不當使用閉包技術,將會加重瀏覽器負擔破,壞用戶體驗。因此提出對閉包技術弊端的解決方案,將有助于改善Web應用性能。

參考文獻:

[1] 周愛民.JAVASCRIPT語言精髓與編程實踐[M].北京:電子工業出版社,2008.

[2] DOM.http://www.w3school.com.cn/htmldom/index.asp[EB/OL].

[3] Michael Moncur.Sams Teach Yourself JavaScript in 24 Hours[M].4th ed.Sams publishing,2007.

主站蜘蛛池模板: 午夜视频www| 欧美一区二区福利视频| 91在线精品免费免费播放| 五月综合色婷婷| 久久香蕉欧美精品| 不卡无码h在线观看| 免费va国产在线观看| 日本在线免费网站| 国产在线91在线电影| 欧美高清视频一区二区三区| 亚洲无线国产观看| 无码国产偷倩在线播放老年人| 伊人久久大香线蕉影院| 国产无码制服丝袜| 毛片大全免费观看| 男人天堂亚洲天堂| 精品一区二区三区视频免费观看| 综合网久久| 黄色污网站在线观看| 亚洲第一区精品日韩在线播放| 国产精品55夜色66夜色| 亚洲精品福利网站| 国产一区二区网站| 无码av免费不卡在线观看| 人妻中文久热无码丝袜| 日本不卡免费高清视频| 亚洲伊人天堂| 久热re国产手机在线观看| 国产精品亚洲五月天高清| 亚洲熟女偷拍| 国产农村妇女精品一二区| www亚洲精品| 婷婷色狠狠干| 国产精品va免费视频| 欧美精品亚洲日韩a| 国产成本人片免费a∨短片| 国产午夜精品一区二区三区软件| 色综合天天视频在线观看| 亚洲一区二区三区在线视频| 欧美午夜视频在线| 日韩黄色精品| 四虎国产精品永久一区| 国产sm重味一区二区三区| 在线高清亚洲精品二区| 啪啪永久免费av| 91视频99| 亚洲Aⅴ无码专区在线观看q| 亚洲精品亚洲人成在线| 欧美性久久久久| 亚洲人在线| 国产一区二区三区在线观看视频 | 国产美女一级毛片| www中文字幕在线观看| 精品国产一区二区三区在线观看| 欧美日韩一区二区在线免费观看| 日韩欧美国产精品| 免费在线不卡视频| 婷婷六月天激情| 亚洲视频无码| 毛片最新网址| 四虎综合网| 性视频久久| 亚洲AⅤ波多系列中文字幕| 精品剧情v国产在线观看| 午夜丁香婷婷| 成年午夜精品久久精品| 亚洲无码精品在线播放| 香蕉99国内自产自拍视频| 国产精品成| 亚洲国产日韩欧美在线| 亚洲精品图区| 天堂久久久久久中文字幕| 少妇精品网站| 日韩国产另类| 亚洲啪啪网| 男人天堂亚洲天堂| 天堂网亚洲系列亚洲系列| 精品伊人久久久久7777人| 亚洲中文字幕国产av| 亚洲综合专区| 日本日韩欧美| 国产呦视频免费视频在线观看|