深入理解 JavaScript 數(shù)組的特性與最佳實踐

JavaScript 提供了一種類似數(shù)組特性的對象,它把數(shù)組的下標變?yōu)樽址?,作為對象的屬性。雖然它比一個真正的數(shù)組來的慢,但是使用起來很方便。

1 數(shù)組字面量

數(shù)組字面量是在一對方括號中包圍零個或多個用逗號分隔的值的表達式:

var empty = [];
var numbers = [
    'zero', 'one', 'two', 'three'
];
console.log(empty[1]);//undefined
console.log(numbers[1]);//one
console.log(empty.length);//0
console.log(numbers.length);//4

數(shù)組對象繼承自 Array.prototype,所以 numbers 繼承了大量有用的方法。

JavaScript 允許數(shù)組包含任意混合類型的值:

var misc = [
    'string', 11.3, false, true, null, undefined, ['nested', 'array'], {object: true}, NaN, Infinity
];
console.log(misc.length);//10

2 長度

數(shù)組有一個 length 屬性,但它是沒有上界的。如果用大等于當前 length 的數(shù)字作為下標來存儲元素,那么 length 屬性值會被增大以便容納新的元素,而不會發(fā)生數(shù)組越界現(xiàn)象哦O(∩_∩)O~

length 屬性的值很詭異,它是數(shù)組最大整數(shù)屬性名加 1,即它不一定等于數(shù)組的元素個數(shù):

var myArray = [];
console.log(myArray.length);//0

//myArray 只包含一個屬性,但 length 的值等于這個數(shù)組最大整數(shù)的屬性名加 1
myArray[100000] = true;
console.log(myArray.length);//100001

[] 后置運算符會把它包含的表達式轉(zhuǎn)換為字符串,如果表達式有 toString() 方法,那么就會調(diào)用它。這個字符串被當做屬性名,如果這個字符串是一個大等于當前 length 值而且小于 4294967295 的正整數(shù),那么這個數(shù)組的 length 就會被重置為新的下標加 1。

可以直接設(shè)置 length 的值。設(shè)置更大的 length 值不會為數(shù)組分配更多的空間;而把 length 設(shè)小則會導(dǎo)致所有下標大等于新的 length 的屬性被刪除:

//刪除元素
numbers.length = 3;
console.log(numbers);//[ "zero", "one", "two" ]

把下標指定為數(shù)組的當前 length,就可以把一個新元素附加到數(shù)組的尾部:

//新增元素
numbers[numbers.length] = 'four';
console.log(numbers);//[ "zero", "one", "two", "four" ]

使用 push() 可以更方便地實現(xiàn)同樣的功能:

//新增元素(push)
numbers.push('good');
console.log(numbers);//[ "zero", "one", "two", "four", "good" ]

3 刪除

JavaScript 數(shù)組就是對象,所以可以用 delete 移除元素:

delete numbers[2];
console.log(numbers);//[ "zero", "one", <1 個空的存儲位置>, "four", "good" ]

可惜的是,這會在數(shù)組中留下一個空洞!而我們希望的是:刪除后,被刪除元素的后續(xù)元素會自動地往前移動。

JavaScript 數(shù)組提供了 splice() 方法,它接受下列參數(shù):

  1. 數(shù)組的索引。
  2. 要刪除的元素個數(shù)。
  3. 其他參數(shù)(多個)- 把這些參數(shù)依次插入到索引位置。
//第一個參數(shù)是索引號,第二個參數(shù)是要刪除的元素個數(shù)
numbers.splice(2, 1);
console.log(numbers);// [ "zero", "one", "four", "good" ]

4 枚舉

JavaScript 數(shù)組是對象,所以可以用 for in 語句來遍歷數(shù)組的所有屬性??墒?for in 語句無法保證屬性的順序,而且可能從原型鏈中得到意外的屬性。

可以使用 for 來避免上述的問題:

var i,
    myArray = numbers;
for (i = 0; i < myArray.length; i += 1) {
    console.log(myArray[i]);
}

5 數(shù)組與對象

如何在這兩者進行選擇?當屬性名是小而連續(xù)的整數(shù)時,使用數(shù)組;否則使用對象。

JavaScript 的 typeof 會認為數(shù)組是 object,這沒有意義!

我們可以定義一個函數(shù)來檢測數(shù)組:

var is_array = function (value) {
    return value && typeof value === 'object' &&
        value.constructor === Array;
};

這個方法在不同窗口(window)或框架(frame) 里構(gòu)造的數(shù)組會失敗。所以請用下面的這個更好的方法:

var is_array = function (value) {
    return Object.prototype.toString.apply(value) === '[object Array]';
};
console.log(is_array(myArray));//true

6 方法

JavaScript 提供了一些對于數(shù)組可用的方法,它們被存儲在 Array.prototype 中。我們可以為數(shù)組增加一個對數(shù)組進行計算的方法:

//新增可以對數(shù)組中的元素進行計算的方法
Array.method('reduce', function (f, value) {
    var i;
    for (i = 0; i < this.length; i += 1) {
        value = f(this[i], value);
    }
    return value;
});

這樣所有的數(shù)組都繼承了這個方法。它接受一個函數(shù)與初始值為參數(shù)。然后遍歷數(shù)組,并通過函數(shù)計算出新值,最后返回這個值。

//創(chuàng)建數(shù)字數(shù)組
var data = [9, 16, 32, 192, 8];

//定義加法與乘法函數(shù)
var add = function (a, b) {
    return a + b;
};
var mult = function (a, b) {
    return a * b;
};

console.log(data.reduce(add, 0));//257
console.log(data.reduce(mult, 1));//7077888

因為數(shù)組就是對象,所以也可以直接給數(shù)組添加方法:

data.total = function () {
    return this.reduce(add, 0);
};
console.log(data.total());//257

因為字符串 “total” 不是整數(shù),所以不會改變數(shù)組的 length 值。當屬性名是字符串時,它就會成為數(shù)組的屬性。

7 指定初始值

如果使用 [] 得到的新數(shù)組,它將是空的。這是如果訪問它,將會得到 undefined。我們可以實現(xiàn)一個可以初始化數(shù)組元素值的方法:

//為每一個元素指定初始值
Array.dim = function (dimension, initial) {
    var a = [], i;
    for (i = 0; i < dimension; i += 1) {
        a[i] = initial;
    }
    return a;
};

//創(chuàng)建包含 10 個 0 的數(shù)組
var myArray = Array.dim(10, 0);
console.log(myArray);//[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

JavaScript 數(shù)組的元素可以是數(shù)組,通過這種方式來實現(xiàn)多維數(shù)組功能:

//數(shù)組的數(shù)組
var matrix = [
    [0, 1, 2], [3, 4, 5]
];
console.log(matrix[1][0]);//3

可以擴展 Array 方法,讓它可以初始化矩陣:

/**
 *
 * @param m 第一維個數(shù)
 * @param n 第二維個數(shù)
 * @param initial 初始值
 */
Array.matrix = function (m, n, initial) {
    var a, i, j, mat = [];
    for (i = 0; i < m; i += 1) {
        a = [];
        for (j = 0; j < n; j += 1) {
            a[j] = initial;
        }
        mat[i] = a;
    }
    return mat;
};

//構(gòu)造 0 填充的 4*4 矩陣
console.log(Array.matrix(4, 4, 0));

//構(gòu)造單元矩陣
Array.identity = function (n) {
    var i, mat = Array.matrix(n, n, 0);
    for (i = 0; i < n; i += 1) {
        mat[i][i] = 1;
    }
    return mat;
};
var myMatrix = Array.identity(4);
console.log(myMatrix);
console.log(myMatrix[3][3]);//1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、JS前言 (1)認識JS 也許你已經(jīng)了解HTML標記(也稱為結(jié)構(gòu)),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,932評論 0 8
  • 第1章 認識JS JavaScript能做什么?1.增強頁面動態(tài)效果(如:下拉菜單、圖片輪播、信息滾動等)2.實現(xiàn)...
    mo默22閱讀 1,512評論 0 5
  • 女兒從小就是我的驕傲,聰慧好學(xué),乖巧懂理,是好多孩子心中的榜樣。沒想到,五年級那年,一記悶棍把我打蒙圈了。 五年級...
    開心就笑吧閱讀 139評論 0 2
  • 因我需要參加一場在異地舉行的考試,考慮其路途的遠近以及轉(zhuǎn)車的繁瑣,于是慎重地向媽媽提出獨自驅(qū)車前往。媽媽提出我...
    車馬正簡閱讀 279評論 0 0
  • 因為Google Doodle,第一次認識到了二十四節(jié)氣。 來自百度百科的解釋 一年有二十四個節(jié)氣,計十二個節(jié)和十...
    太陽融化了我閱讀 1,414評論 2 1

友情鏈接更多精彩內(nèi)容