摘要:內部屬性包含一個函數被創建的作用域中的對象的集合,此集合被稱為函數的作用域鏈。當作用域鏈銷毀時,激活對象一同被銷毀。下圖展示了函數運行期上下文的作用域和閉包由于閉包的屬性包含與運行期上下文作用域鏈相同的對象引用,會產生副作用。
javascript按照數據存儲位置的不同可分為以下四類:
直接量(字符串、數字、布爾型、Object、Array、Function、正則表達式、NULL以及undefined)。
變量。
數組項。
對象成員。
javascript對以上四個類型數據的訪問速度依次減慢,也就是說,訪問直接量的速度是最快的,而訪問對象成員的消耗的時間是最多的。
管理作用域理解作用域是理解javascript的關鍵。作用域對javascript有非常多的影響,從知道哪些變量可以被訪問,到確定this的值。javascript作用域也關系到性能。
作用域鏈每一個javascript函數都可以看作一個對象,進一步說,它是一個函數實例。函數對象和其他的對象一樣,擁有可編程訪問屬性和內部屬性,其中[[Scope]]就一個典型的內部屬性。
內部屬性[[Scope]]包含一個函數被創建的作用域中的對象的集合,此集合被稱為函數的作用域鏈。他決定那些數據可以用函數訪問。此函數中的每個對象被稱為可變對象。當一個函數被創建后,它的作用域鏈被填充以對象,這些對象代表創建此函數的環境可以訪問的數據。例如下面這個全局函數:
function add(a,b) { var sum = a + b; return sum; }
當add()函數被創建后,它的作用域鏈被填入一個多帶帶的可變對象,此全局對象代表所有全局范圍內定義點變量。當add()函數運行時,會創建一個“運行期上下文”。一個運行期上下文定義了一個函數運行時的環境,所以多次調用同一個函數會產生多個運行期上下文。當函數執行完畢,運行期上下文就會被銷毀。
一個運行期上下文有它自己的作用域鏈,用于標識符解析。當運行期上下文被創建時,作用域鏈為初始化,連同運行函數的[[Scope]]屬性中所包含的對象。這些值按照它們在函數中出現的順序被復制到運行期上下文所在的作用域鏈中。這項工作一旦完成,一個稱為“激活對象”的新對象就為運行期上下文準備好了。此激活對象是一個可變對象,包含訪問所有局部變量、命名參數、參數集合,和this接口。然后此對象推入作用域鏈的前端。當作用域鏈銷毀時,激活對象一同被銷毀。下圖展示了實例代碼對應的運行期上下文:
在函數運行過程當中,每遇到一個變量,函數就從這個作用域鏈中依次進行查找,正是這種查找過程影響了性能。一個標識符所處的位置越深,讀寫它的速度就越慢。所以,當一個函數中,如果要頻繁的調用一個全局變量,那么最好用一個局部變量把它保存下來。
閉包閉包是javascript最強大的一面,它允許函數訪問局部范圍之外的數據。為了了解與閉包有關的性能問題,我們看下面的例子:
function assignEvents(){ var id = "123"; document.getElementById("savaBtn").onclick = function(e) { savaDocument(id); }; }
assignEvents()函數為一個DOM元素指定了一個時間處理函數。此事件處理函數就是一個閉包,在assignEvents()執行時創建,這個閉包可以訪問其范圍內部的id變量。下圖展示了函數運行期上下文的作用域和閉包:
由于閉包的[[Scope]]屬性包含與運行期上下文作用域鏈相同的對象引用,會產生副作用。通常,一個函數的激活對象與運行期上下文一同銷毀。當涉及閉包時,激活對象就無法銷毀了。這意味著,閉包與非閉包函數相比,需要消耗更多的內存。
當一個閉包被執行時,它的作用域鏈與[[Scope]]中引用的兩個相同的作用域鏈同時被初始化,然后一個新的激活對象為閉包自身所創建。如下圖所示:
注意閉包中使用的兩個標識符:id和saveDocument,他們并不是在作用域鏈中的最前端,這就造成了數據讀寫的性能問題。
javascript中的對象是基于原型的,原型是其他對想的基礎,定義一個新的對象必須具有的成員。對象成員分為實例成員和原型成員,你可以通過hasOwnProperty()函數來確定某個成員是否為實例成員。要確定某個對象是否有某個屬性,可以用in關鍵字來確定。
原型鏈可以通過prototype屬性來構造原型鏈,但是要注意的是:對象在查找成員的過程就像函數作用域鏈查找變量的過程類似,先查找實例成員,如果找不到再從原型成員中查找,所以也有類似的性能問題。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87589.html
摘要:此過程中,頁面的解析與用戶的交互都是阻塞的。非阻塞腳本延時腳本可以給標簽添加一個屬性,這個屬性表明元素中的腳本不打算修改,因此代碼可以稍后執行。此技術的重點在于無論在何處啟動下載,腳本的下載和運行都不會阻塞頁面的處理過程。 當瀏覽器遇到標簽時,頁面的加載、介些都會停下來,運行此javascript代碼,然后再繼續加載。這種事情同樣會發生在那些以src屬性調用的外部腳本,瀏覽器首先下載外...
摘要:操作的代價非常昂貴,對元素節點的訪問和修改樣式布局的改變以及事件的綁定都影響著網頁的性能。所以,盡量減少對布局信息的查詢次數,并用局部變量參與計算。當動畫結束時,重新定位,從而只一次下移文檔其他元素的位置。這樣可以最小化事件句柄數量。 DOM操作的代價非常昂貴,對元素節點的訪問和修改、樣式、布局的改變以及DOM事件的綁定都影響著網頁的性能。 批量修改DOM 如果要對元素節...
摘要:無主題,內容為感觸較深的一些答疑探討等,摘自多篇文章,侵刪為什么是單線程的單線程,與它的用途有關。作為瀏覽器腳本語言,的主要用途是與用戶互動,以及操作。這決定了它只能是單線程,否則會帶來很復雜的同步問題。摘自運行機制詳解再談作者阮一峰 無主題,內容為感觸較深的一些答疑、探討等,摘自多篇文章,侵刪 1、為什么JavaScript是單線程 JavaScript的單線程,與它的用途有關。作...
摘要:剛學了一些的基礎語法,試著用一下。相關文檔基本語法配合基本使用相同點和都是的基本數據類型擴展的種基本數據類型和都是值擴展的種值空字符串不同點可見代表變量有值,值為空且該值是通過變量賦值獲得的代表聲明了變量,但沒有為其賦值。 剛學了一些 Markdown 的基礎語法,試著用一下。 相關文檔:Markdown基本語法配合基本使用 相同點: null 和 undefined 都是js...
摘要:而在這個運算符的相關用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。即對象的淺拷貝會對主對象的值進行拷貝,而該值有可能是一個指針,指向內存中的同一個對象。,可以看到深拷貝和淺拷貝是對復制引用類型變量而言的。 在ES6的系列文章中,基本都會提到Spread——擴展運算符(...)。而在這個運算符的相關用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。 背景知識 在討...
閱讀 3036·2021-11-02 14:40
閱讀 849·2019-08-30 15:53
閱讀 1267·2019-08-30 15:53
閱讀 3264·2019-08-30 13:53
閱讀 3308·2019-08-29 12:50
閱讀 1138·2019-08-26 13:49
閱讀 1869·2019-08-26 12:20
閱讀 3666·2019-08-26 11:33