上一篇說了數組的索引,這篇說下數組的使用。
陣列的大小
js的陣列可以動態調整大小,更確切地說,它沒有陣列越界的概念,a[a.length]沒什麼問題。例如宣告一個陣列a = [1, 3, 5],現在的陣列大小是3,最後一個元素的索引是2,但是你依然可以使用a[3],存取a[3]返回的是undefined,給a[3]賦值:a[3] = 7,是為陣列a增加了一個元素,現在陣列a的長度是4了。你可以試試看把下面這段程式碼放到瀏覽器裡運行下:
var a = []; for(int i = 0; i <= a.length; i++) { a[a.length] = i; }
在我的電腦上,火狐會立刻崩掉,chrome這一個標籤cpu佔用99%(使用chrome的任務管理員查看的)。
js的length的值會隨著數組元素的改變而改變,當然你也可以手動設定數組的length 屬性,設定更大的length不會給數組分配更多的空間,但是設置更小的length則會導致所有下標大於等於新length的屬性被刪除。
另外有一點就是,數組的length值是怎麼來的,有的資料說是最大一個數字索引值加一,應該是對的,不過如果把空槽也算數的話,length值就是數組的元素數。上張圖解釋下:
從圖裡可以看到,有個數組a,a[0]和a[10]都已賦值,這時候a的length是11,中間有9個empty slot(姑且就翻譯為空槽好了)。那這九個空槽算不算數呢,我覺得應該算,這樣就能合理的解釋length值了。那這些空槽的值是什麼呢? undefined!所以呢,如果在chrome裡,使用foreach遍歷(forin),那麼這些空槽正好都能跳過,而使用for遍歷,則會列印出undefined。至於在firefox裡,表現不太一樣,自己試試看。
陣列的遍歷
昨天在看微博上轉的js教程的時候,裡面說在遍歷數組的時候,判斷語句i 關於陣列的foreach遍歷,js的方式相對於java/c#等語言是很奇怪的: 可以看到,列印的結果不是陣列的元素,而是數字索引值(感覺這好像也可以說明,js的陣列也是用hash的方式儲存的),不管怎樣,這一點要注意。 (至於為什麼這樣,我覺得數組元素都是數組的屬性,這個遍歷是遍歷的length值,從0到length。而不是逐個輸出數組的元素,因為元素是屬性,數組又不只數字索引這一種屬性,那麼為什麼這樣遍歷的時候只輸出它們呢,而不是length,push,join等方法? 數組的一些方法 陣列有push和pop方法,這樣陣列就像堆疊一樣了。對數組使用delete,可以將數組中某個元素移除,但是那樣會在數組中留下一個空洞(也就是說delete也可以刪除數組中的元素,但是只是刪除該位置的值,不改變數組大小,原位置類型是undefined),這是因為排在被刪除元素之後的元素保留著它們最初的屬性,所以應該使用splice對進行過delete操作的數組進行瘦身,它會將被刪除的屬性移除,但這樣效率並不是很高。陣列中還有map、reduce、filter等方法,這裡就不多說了(跟python中的list挺像的)。 補充 最後補充一點,我前面說過,js中的陣列就是物件(廢話,本來就是物件),那麼是不是說,陣列和物件可以互相互相替換著用呢?答案是可以的。不過為了明確,還是分開用比較好,下面說下什麼時候該用數組,什麼時候該用對象(參考《javascript語言精粹》): 當屬性名稱是小而連續的整數時,應該使用陣列,否則,使用物件。 番外 覺得閉包被神化了,可能語言層面上的實現有技術,但是在應用層面我覺得就應該那樣啊,使用的時候都感覺不到那是在用閉包。但這個閉包卻幾乎成了面試前端必問的概念了。 以上所述就是本文的全部內容了,希望大家能夠喜歡。
for(var name in ['huey', 'dewey', 'louie']) {
console.log(name);
}
/*
打印结果:
0
1
2
*/
另外由於js中對陣列和物件使用 typeof 的結果都是 Object,因此判斷一個物件是否為陣列的方法:
var is_array = function(value) {
return Object.prototype.toString.apply(value) === '[object Array]';
};