第二章 數據訪問
數據存儲的位置關係到代碼運行時,被檢索的速度。
1. JavaScript中的數據存儲
1. 直接量: 代表自身,不存儲在任何位置。字符串,數字,布爾值,數組,對象,undifined,null等等。
2. 變量:使用var來存儲的數據值。
3. 數組項:具有數字索引,存儲javascript數組對象。
4. 對象成員:具有字符串索引,存儲javascript對象。
訪問直接量和局部變量的速度差不多,要優於數組項和成員對象。
例外:firefox3優化過的數組項訪問速度非常快。
2.變量和標識符
變量:javascript中的變量是鬆散類型的,可以保存任何類型的數據。由於不存在定義某個變量必須要保存何種數據類型值的規則,變量的值及其數據類型可以在腳本的生命週期內改變
標識符:變量的名字
標識符解析是沿着作用域鏈一級一級地搜索標識符的過程。搜索過程始終從作用域鏈的前端開始,然後逐級地向後回溯,直到找到標識符爲止。
每個運行上下文都有自己的作用域鏈用來解析標識符,當運行上下文被創建時,該作用域鏈被初始化,之前得[scope]複製進作用鏈最底層,同時會創建一個名叫’激活對象’的可變對象,他包含局部變量,參數,以及this指針。被壓入作用域鏈頂層。
3.管理作用域
2.1作用域鏈和標識符解析
javascipt中任何數據類型都可以稱之爲對象,那麼函數也不例外。
//原型鏈的最頂層是object,
//構造函數的最頂層是Function。
那麼函數也具有可以編程使用的屬性,和一些javascript引擎提供的內置屬性。其中一個就是[scope]
scope屬性
內部[scope]包含了一個函數被創建時作用域對象的集合。這些對象的集合被稱作作用域鏈。函數作用域鏈中的每個對象被稱爲可變對象。可變對象是以鍵值對的形式存在。當函數被訪問時會創建一個可供函數作用域訪問的數據對象。
例如下面這個全局函數:
function Add(num1,num2){
var sum = num1 + num2;
return sum;
}
被創建時作用域如下圖所示:
當add函數被創建時,首先會在作用域鏈中注入一個全局對象,該對象包含所有全局作用域中的變量,例如窗口瀏覽器,this指針,全局變量等。
當函數被執行時
Add(1,2)
當函數被運行時,會創建一個“運行期上下文”,該上下文定義了函數運行期的環境,該運行期上下文是獨一無二的。每次執行函數都會創建一個運行期上下文,導致反覆執行,當函數執行完成,該運行期上下文被銷燬。
當函數運行時,每遇到一個變量,會搜索運行期上下文,沿着作用於鏈一個對象一個對象向下搜索,先搜索’激活對象’,如果搜索到了,就是用標識符匹配這個變量。否則往下搜索直到全局對象,如果還未找到。就會返回null,或者報錯。
總結:
- 在javascript中,數據儲存的位置 對代碼整體性能的影響十分的重要,共有四種數據類型:直接量,變量,數組項,對象成員。
- 直接量和局部變量訪問的速度最快,數組項和對象成員可能需要更長的時間。
- 避免使用with表達式,因爲它改變了運行期上下文的作用域鏈。
- 嵌套對象成員會對性能有重大的影響所以儘量少用
- 提升javascript的方法:將經常使用的數組項,全局變量,對象成員引入函數,使之成爲局部變量。然後引用局部變量的速度會遠遠高於原始變量