JavaScript數組基礎知識
前言:
其實作為一個Java程式員,對JS程式一直都有點“不屑一顧”的感覺,很多人肯定和我一樣,有其他語言基礎,JS文法根本就懶得看,直接寫程式,一般工作也都夠用了。但是最近在做一個偏Web Excel項目,需要大量的JS編程和最佳化,抽空又“惡補”了下JS基礎。發現原來對JS的理解偏差還是很大的。不過JS這個東西深入起來其實比Java要容易的。
基礎:
JS數組和Java數組很類似,值都是有序的,索引從0開始。但是JS數組最大可能的索引為2的32次最大能容納4294967295個元素。但是和Java數組不同的是,JS數組是動態,不用指定初始大小,可以是稀疏的,下標不一定連續。訪問到不存在的元素則返回undefined。最重要的是JS數組貫穿了JS中一切都是對象的概念,JS數組可以當成普通對象處理,這也是基於索引訪問JS數組的“實質”。
一切都是對象:
JS中一切都是對象(單身狗又要落淚了),數組是對象的特殊形式。使用括弧訪問數組元素就像用方括弧訪問對象的屬性一樣。JS會把數字索引轉換為字串形式:1 -> “1”。所以這導致了JS數組的下標可以不連續,也就是a[2]後面可以直接跟a[5]而不存在a[3]和a[4]。
特殊點:
JS數組的特別之處在於,當使用非負整數作為屬性名稱時JS數組會自動維護length屬性值。Java的length屬性是在初始時指定的,不會動態維護。
數組是特殊的對象,可以為其建立任意名字的屬性,但是如果使用的屬性是數組的索引(也就是說用數字訪問數字索引),數組的特殊行為就是將根據需要更新它們的length屬性。
在早期瀏覽器中,使用JS數組效率並不是很高,原因就是用數組索引方式訪問資料,JS引擎搜尋JS數組對象耗時和訪問普通屬性是差不多的,甚至更差。但是現代瀏覽器很多JS引擎都最佳化過這部分功能了,所以用索引的方式還是蠻快的。至於會不會比查詢普通屬性要快沒有驗證過。JS數組在維護length值是有兩個特殊行為:
1.如果某個元素的index大於或者等於length,則length變為index + 1;
2.如果設定length小於某個值,那麼index大於和等於length的元素全部被刪除;
注意點:
在Java中數組的length屬性是唯讀,Java數組的length屬性是被標記為final的,所以無法運行時修改,但是JS是允許我們讀取和修改的。
訪問JS數組元素時應該注意的是我們是給對象建立了一個屬性還是訪問的數組元素。這影響的是JS length屬性的值。
比如:
a[“a”]在數組中也是允許的不過它訪問的是數組對象a的屬性a
a[1.00] 等同 a[1] 等同 a[“1”] 等同a[“1.0”],他們都訪問的是數組對象a的第一個元素,a會委會length屬性。
遍曆最佳化
由於JS屬於解釋性語言,JS查詢局部變數比物件變數要快,它不用去原型鏈尋找迭代,所以很多時候JS最佳化都會用一個局部變數引用一些查詢層次比較高的變數。所以JS數組遍曆最佳化主要是兩個,一個是針對length屬性,另一個是針對數組元素,用兩個局部變數緩衝他們能提高些效率。
var temp = null;for(var i = 0 , len = keys.length ; i
稀疏數組
JS數組也分為稀疏數組和稠密數組,但是JS稀疏數組和Java的是不一樣的。JS中足夠稀疏的數組通常在實現上比稠密的數組更慢,但是記憶體利用率更高。
用數組直接量(就是 var a= []方式)不會建立稀疏數組,在JS數組中省略的元素是undefined這和元素不存在是有微妙的區別的。在Java中省略不初始化,數組元素都是null,也就是它是佔有記憶體空間的,但是JS中不一樣。在JS中可以用in監測數組元素是否存在:
var a =[,,]0 in a;
JS數組——隊列——棧的關係
JS數組是一個對象,所以可以認為它是一個Map,實際上JS的對象都可以認為是一個Map,所以在JS中我們沒必要太過於去實現一個HashMap。在Java中我們通過數組通常會實現Stack和queue兩種資料結構。在JS中JS數組提供了一些列方法,讓JS本身就具有這兩種資料結構的行為。
(1)棧行為:JS數組擁有push和pop方法,同資料結構中規定的push和pop是一樣的。
(2)隊列行為:JS數組還擁有unsift,shift方法,用來向對頭插入、彈出資料,結合push和pop可以進行出隊、入隊操作。
(3)JS數組比較麻煩的是刪除中間元素,比如要刪除a[2],可以用delete或者splice方法,但是都不是很完美。
其他方法:
(1)join串連數組成一個字串
(2)reverse顛倒元素
(3)sort排序數組
傳入一個function返回一個數值,小於0則交換位置
(4)concat串連兩個數組
(5)slice返回指定數組的一個片段或子數組
JS數組還有很多其他“奇妙”用途,和最佳化要點。看來每種語言都不可小覷。