上一篇說了數組的索引,這一篇說下數組的使用。javascript
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的任務管理器查看的)。java
js的length
的值會隨着數組元素的改變而改變,固然你也能夠手動設置數組的 length
屬性,設置更大的length
不會給數組分配更多的空間,可是設置更小的length
則會致使全部下標大於等於新length
的屬性被刪除。python
另外有一點就是,數組的length
值是怎麼來的,有的資料說是最大一個數字索引值加一,應該是對的,不過若是把空槽也算數的話,length
值就是數組的元素數。上張圖解釋下:面試
從圖裏能夠看到,有個數組a,a[0]
和a[10]
都已賦值,這時候a的length
是11,中間有9個empty slot(姑且就翻譯爲空槽好了)。那這九個空槽算不算數呢,我以爲應該算,這樣就能合理的解釋length
值了。那這些空槽的值是什麼呢?undefined!因此呢,若是在chrome裏,使用foreach遍歷(forin),那麼這些空槽正好都能跳過,而使用for遍歷,則會打印出undefined。至於在firefox裏,表現不太同樣,本身試吧。chrome
昨天在看微博上轉的js教程的時候,裏面說在遍歷數組的時候,判斷語句i<a.length
會形成每循環一次都要計算一次長度,從而對性能有一點點影響。這一點我表示疑問,我不肯定究竟是不是這樣,並且不一樣的瀏覽器對這種狀況可能還有不一樣的優化,我在網上搜了下,找到了幾個網頁說了要緩存數組大小,可是都是抄的,沒主見,也沒說明原理,因此我表示很懷疑,並且我在chrome測試了下,性能上沒什麼明顯差別。關鍵是我以爲,length
是個數組的屬性,每次調用a.length
的時候,只是訪問這個屬性而已,屬性都是用hash的方式存儲的,因此訪問的時間複雜度是O(1)。這是個人見解,若是不對,請告訴我。c#
關於數組的foreach遍歷,js的方式相對於java/c#等語言是很奇怪的:數組
for(var name in ['huey', 'dewey', 'louie']) { console.log(name); } /* 打印結果: 0 1 2 */
能夠看到,打印的結果不是數組的元素,而是數字索引值(感受這好像也能夠說明,js的數組也是用hash的方式存儲的),無論怎樣,這一點要注意。(至於爲何這樣,我以爲數組元素都是數組的屬性,這個遍歷是遍歷的length值,從0到length。而不是逐個輸出數組的元素,由於元素是屬性,數組又不僅數字索引這一種屬性,那麼爲何這樣遍歷的時候只輸出它們呢,而不是length,push,join等方法?公平起見,只好輸出數組的數字索引了。固然,這只是我本身的見解,具體怎麼樣我沒研究。)瀏覽器
數組有push
和pop
方法,這樣數組就像堆棧同樣了。對數組使用delete
,能夠將數組中某個元素移除,可是那樣會在數組中留下一個空洞(也就是說delete
也能夠刪除數組中的元素,可是隻是刪除該位置的值,不改變數組大小,原位置類型是undefined
),這是由於排在被刪除元素以後的元素保留着它們最初的屬性,因此應該使用splice
對進行過delete
操做的數組進行瘦身,它會將被刪除的屬性移除,但這樣效率並非很高。數組中還有map
、reduce
、filter
等方法,這裏就很少說了(跟python中的list挺像的)。緩存
最後補充一點,我前面說過,js中的數組就是對象(廢話,原本就是對象),那麼是否是說,數組和對象能夠互相互替換着用呢?答案是能夠的。不過爲了明確,仍是分開用比較好,下面說下何時該用數組,何時該用對象(參考《javascript語言精粹》):
當屬性名是小而連續的整數時,應該使用數組,不然,使用對象。
另外因爲js中對數組和對象使用 typeof 的結果都是 Object,所以判斷一個對象是否爲數組的方法:
var is_array = function(value) { return Object.prototype.toString.apply(value) === '[object Array]'; };
以爲閉包被神化了,可能語言層面上的實現有技術,可是在應用層面我以爲就應該那樣啊,使用的時候都感受不到那是在用閉包。可是這個閉包卻幾乎成了面試前端必問的概念了。