(注1:如果有問(wèn)題歡迎留言探討毯盈,一起學(xué)習(xí)!轉(zhuǎn)載請(qǐng)注明出處病袄,喜歡可以點(diǎn)個(gè)贊哦BЦ场)
(注2:更多內(nèi)容請(qǐng)查看我的目錄。)
1. 簡(jiǎn)介
Array類(lèi)型應(yīng)該是除了Object類(lèi)型外在JS中最常用的類(lèi)型了益缠,JS的數(shù)組與其他多數(shù)語(yǔ)言中的數(shù)組有著相當(dāng)大的區(qū)別脑奠。雖然JS數(shù)組和在其他語(yǔ)言中一樣,是一個(gè)有序列表幅慌,但不同的是其每一項(xiàng)可以保存不同類(lèi)型的的數(shù)據(jù)宋欺,而且其數(shù)組大小是可以動(dòng)態(tài)調(diào)整的。
2. 創(chuàng)建數(shù)組
創(chuàng)建數(shù)組的基本方式有兩種胰伍,即使用Array構(gòu)造函數(shù)齿诞,或者使用數(shù)組字面量語(yǔ)法。
2.1 Array構(gòu)造函數(shù)
使用Array構(gòu)造函數(shù)時(shí)骂租,傳入的參數(shù)有三種情況:
- 沒(méi)有參數(shù)
var arr = new Array()
console.log(arr); // []
會(huì)返回一個(gè)空數(shù)組掌挚,其長(zhǎng)度為0。
- 傳入一個(gè)Number類(lèi)型的整數(shù)值
var arr = new Array(3)
console.log(arr); // [empty × 3]
console.log(arr.length); // 3
console.log(arr[1]); // undefined
會(huì)返回一個(gè)長(zhǎng)度是傳入值且每一項(xiàng)都是undefined的數(shù)組菩咨。注意如果傳入0會(huì)是一個(gè)空數(shù)組,而傳入NaN, Infinity,3.1等無(wú)效長(zhǎng)度則會(huì)報(bào)錯(cuò)抽米。
- 傳入一個(gè)非Number類(lèi)型特占,或者傳入多個(gè)參數(shù)
var arr = new Array('3');
console.log(arr); // ["3"]
arr = new Array(undefined);
console.log(arr); // [undefined]
arr = new Array(1, '2', {a: 1}, null);
console.log(arr); // [1, "2", {a: 1}, null]
返回參數(shù)按順序組成的數(shù)組。
ps:使用Array()構(gòu)造符時(shí)可以省略new操作符云茸,結(jié)果相同是目。
2.2 數(shù)組字面量語(yǔ)法
var arr1 = [];
var arr2 = [1];
var arr3 = ['1', {a: 1}, undefined];
與對(duì)象一樣,使用數(shù)組字面量語(yǔ)法并不會(huì)調(diào)用Array構(gòu)造函數(shù)标捺。
3. Array構(gòu)造函數(shù)的屬性與方法
我們用Object.getOwnPropertyNames()方法獲取Array構(gòu)造函數(shù)的所有屬性與方法懊纳。
Object.getOwnPropertyNames(Array);
// (6) ["length", "name", "prototype", "isArray", "from", "of"]
發(fā)現(xiàn)一共有6個(gè)屬性和方法。
3.1 Array構(gòu)造函數(shù)的屬性
Array.length
長(zhǎng)度為1
Array.name
名稱(chēng)為"Array"
Array.prototype
指向Arrayt構(gòu)造函數(shù)的原型亡容,可以為所有 Array 類(lèi)型的對(duì)象添加屬性嗤疯。
3.2 Array構(gòu)造函數(shù)的方法
Array.from()
從一個(gè)類(lèi)似數(shù)組或可迭代對(duì)象中創(chuàng)建一個(gè)新的數(shù)組實(shí)例。(ES6新增方法闺兢,會(huì)在ES6專(zhuān)題中進(jìn)行詳細(xì)講解)
語(yǔ)法:
Array.from(arrayLike, mapFn, thisArg)
參數(shù):
- arrayLike
想要轉(zhuǎn)換成數(shù)組的偽數(shù)組對(duì)象或可迭代對(duì)象茂缚。 - mapFn (可選參數(shù))
如果指定了該參數(shù),新數(shù)組中的每個(gè)元素會(huì)執(zhí)行該回調(diào)函數(shù)屋谭。 - thisArg (可選參數(shù))
可選參數(shù)脚囊,執(zhí)行回調(diào)函數(shù) mapFn 時(shí) this 對(duì)象。
返回值:
一個(gè)新的數(shù)組實(shí)例桐磁。
Array.isArray()
用于檢測(cè)傳遞的值是否是一個(gè)數(shù)組悔耘。
Array.isArray([1, 2, 3]); // true
Array.isArray({foo: 123}); // false
Array.isArray("foobar"); // false
Array.isArray(undefined); // false
注意:當(dāng)檢測(cè)Array實(shí)例時(shí), Array.isArray 優(yōu)于 instanceof,因?yàn)锳rray.isArray能檢測(cè)iframes我擂。
Polyfill:
假如不存在 Array.isArray()衬以,則在其他代碼之前運(yùn)行下面的代碼將創(chuàng)建該方法。
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
Array.of()
創(chuàng)建一個(gè)具有可變數(shù)量參數(shù)的新數(shù)組實(shí)例扶踊,而不考慮參數(shù)的數(shù)量或類(lèi)型泄鹏。
Array.of()和Array構(gòu)造函數(shù)之間的區(qū)別在于處理單個(gè)整數(shù)參數(shù):
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
4. Array原型對(duì)象的屬性與方法
我們用Object.getOwnPropertyNames()方法獲取Array原型對(duì)象的所有屬性與方法。
Object.getOwnPropertyNames(Array.prototype);
// (30) ["length", "constructor", "concat", "pop", "push", "shift", "unshift", "slice", "splice", "includes", "indexOf", "keys", "entries", "forEach", "filter", "map", "every", "some", "reduce", "reduceRight", "toString", "toLocaleString", "join", "reverse", "sort", "lastIndexOf", "copyWithin", "find", "findIndex", "fill"]
發(fā)現(xiàn)一共有30個(gè)屬性和方法秧耗。
4.1 Array原型對(duì)象的屬性
Array.prototype.constructor
指向構(gòu)造函數(shù)Array
Array.prototype.length
Array.prototype 也是個(gè)數(shù)組备籽,長(zhǎng)度為0
4.2 Array原型對(duì)象的方法
Array原型對(duì)象的方法分為四類(lèi):
- 修改器方法
- 訪(fǎng)問(wèn)方法
- 迭代方法
- 泛型方法(已棄用)
4.2.1 修改器方法
修改器方法會(huì)改變調(diào)用它們的對(duì)象自身的值。
Array.copyWithin()
淺復(fù)制數(shù)組的一部分到同一數(shù)組中的另一個(gè)位置分井,并返回它车猬,而不修改其大小,用該方法移動(dòng)數(shù)組數(shù)據(jù)性能非常高尺锚。
語(yǔ)法:
arr.copyWithin(target[, start[, end]]);
參數(shù):
- target
0 為基底的索引珠闰,復(fù)制序列到該位置。
如果是負(fù)數(shù)瘫辩,target 將從末尾開(kāi)始計(jì)算(索引位置等同于length+start)伏嗜。
如果 target 大于等于 arr.length坛悉,將會(huì)不發(fā)生拷貝。
如果 target 在 start 之后承绸,復(fù)制的序列將被修改以符合 arr.length裸影。 - start
0 為基底的索引,開(kāi)始復(fù)制元素的起始位置军熏。
如果是負(fù)數(shù)轩猩,start 將從末尾開(kāi)始計(jì)算(索引位置等同于length+start)。
如果 start 被忽略荡澎,copyWithin 將會(huì)從0開(kāi)始復(fù)制均践。 - end
0 為基底的索引,開(kāi)始復(fù)制元素的結(jié)束位置摩幔。copyWithin 將會(huì)拷貝到該位置彤委,但不包括 end 這個(gè)位置的元素。如果是負(fù)數(shù)热鞍, end 將從末尾開(kāi)始計(jì)算索引位置等同于length+start)葫慎。
如果 end 被忽略,copyWithin 將會(huì)復(fù)制到 arr.length薇宠。
返回:
被改變的原數(shù)組
var arr = [1, 2, 3, 4, 5];
arr.copyWithin(-2);
// [1, 2, 3, 1, 2]
arr.copyWithin(0, 3);
// [4, 5, 3, 4, 5]
arr.copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]
arr.copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]
Array.fill()
用一個(gè)固定值填充一個(gè)數(shù)組中從起始索引到終止索引內(nèi)的全部元素偷办。
用法:
arr.fill(target[, start[, end]]);
參數(shù):
- value
用來(lái)填充數(shù)組元素的值。 - start 可選
起始索引澄港,默認(rèn)值為0椒涯。 - end 可選
終止索引,默認(rèn)值為 this.length回梧。
返回:
被改變的原數(shù)組
[1, 2, 3].fill(4) // [4, 4, 4]
[1, 2, 3].fill(4, 1) // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2) // [1, 4, 3]
Array.prototype.pop()
從數(shù)組中刪除最后一個(gè)元素废岂,并返回該元素的值。
Array.prototype.push()
將一個(gè)或多個(gè)元素添加到數(shù)組的末尾狱意,并返回新數(shù)組的長(zhǎng)度湖苞。
Array.prototype.reverse()
顛倒數(shù)組中元素的排列順序,即原先的第一個(gè)變?yōu)樽詈笠粋€(gè)详囤,原先的最后一個(gè)變?yōu)榈谝粋€(gè)财骨。
Array.prototype.shift()
刪除數(shù)組的第一個(gè)元素,并返回這個(gè)元素藏姐。
Array.prototype.unshift()
在數(shù)組的開(kāi)頭增加一個(gè)或多個(gè)元素隆箩,并返回?cái)?shù)組的新長(zhǎng)度。
Array.prototype.sort()
對(duì)數(shù)組內(nèi)元素進(jìn)行排序羔杨,并返回排序后的當(dāng)前數(shù)組捌臊。
Array.prototype.splice()
在任意的位置給數(shù)組添加或刪除任意個(gè)元素。
4.2.2 訪(fǎng)問(wèn)方法
不會(huì)改變調(diào)用它們的對(duì)象的值兜材,只會(huì)返回一個(gè)新的數(shù)組或者返回一個(gè)其它的期望值理澎。
Array.prototype.concat()
返回一個(gè)由當(dāng)前數(shù)組和其它若干個(gè)數(shù)組或者若干個(gè)非數(shù)組值組合而成的新數(shù)組逞力。
Array.prototype.includes()
判斷當(dāng)前數(shù)組是否包含某指定的值,如果是返回 true矾端,否則返回 false掏击。
語(yǔ)法:
arr.includes(searchElement[, fromIndex])
參數(shù):
- searchElement
需要查找的元素值。 - fromIndex 可選
從該索引處開(kāi)始查找 searchElement秩铆。如果為負(fù)值,則按升序從 array.length + fromIndex 的索引開(kāi)始搜索灯变。默認(rèn)為 0殴玛。
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
Array.prototype.join()
將一個(gè)數(shù)組(或一個(gè)類(lèi)數(shù)組對(duì)象)的所有元素連接成一個(gè)字符串并返回這個(gè)字符串,默認(rèn)連接符為 ","添祸。
Array.prototype.slice()
方法返回一個(gè)從開(kāi)始到結(jié)束(不包括結(jié)束)選擇的數(shù)組的一部分淺拷貝到一個(gè)新數(shù)組對(duì)象滚粟。原始數(shù)組不會(huì)被修改。
Array.prototype.toSource()
返回一個(gè)由所有數(shù)組元素組合而成的本地化后的字符串刃泌。遮蔽了原型鏈上的同名方法凡壤。該方法非標(biāo)準(zhǔn),不要在生產(chǎn)上使用耙替,僅可用于調(diào)試亚侠。
Array.prototype.toString()
返回一個(gè)由所有數(shù)組元素組合而成的字符串。遮蔽了原型鏈上的同名方法俗扇。
Array.prototype.toLocalString()
返回一個(gè)由所有數(shù)組元素組合而成的本地化后的字符串硝烂。遮蔽了原型鏈上的同名方法。
Array.prototype.indexO()
返回?cái)?shù)組中第一個(gè)與指定值相等的元素的索引铜幽,如果找不到這樣的元素滞谢,則返回 -1。
注意:indexOf 使用strict equality (===操作符基于同樣的方法)進(jìn)行判斷 searchElement與數(shù)組中包含的元素之間的關(guān)系除抛。
Array.prototype.lastIndexOf()
返回?cái)?shù)組中最后一個(gè)(從右邊數(shù)第一個(gè))與指定值相等的元素的索引狮杨,如果找不到這樣的元素,則返回 -1到忽。
4.2.3 迭代方法
在下面的眾多遍歷方法中橄教,有很多方法都需要指定一個(gè)回調(diào)函數(shù)作為參數(shù)。在每一個(gè)數(shù)組元素都分別執(zhí)行完回調(diào)函數(shù)之前绘趋,數(shù)組的length屬性會(huì)被緩存在某個(gè)地方颤陶,所以,如果你在回調(diào)函數(shù)中為當(dāng)前數(shù)組添加了新的元素陷遮,那么那些新添加的元素是不會(huì)被遍歷到的滓走。此外,如果在回調(diào)函數(shù)中對(duì)當(dāng)前數(shù)組進(jìn)行了其它修改帽馋,比如改變某個(gè)元素的值或者刪掉某個(gè)元素搅方,那么隨后的遍歷操作可能會(huì)受到未預(yù)期的影響比吭。總之姨涡,不要嘗試在遍歷過(guò)程中對(duì)原數(shù)組進(jìn)行任何修改衩藤,雖然規(guī)范對(duì)這樣的操作進(jìn)行了詳細(xì)的定義,但為了可讀性和可維護(hù)性涛漂,請(qǐng)不要這樣做赏表。
Array.prototype.forEach()
為數(shù)組中的每個(gè)元素執(zhí)行一次回調(diào)函數(shù)。
注意:該方法沒(méi)有返回值匈仗。
Array.prototype.entries()
返回一個(gè)數(shù)組迭代器對(duì)象瓢剿,該迭代器會(huì)包含所有數(shù)組元素的鍵值對(duì)。
var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined
console.log(iterator);
// Array Iterator {}
console.log(iterator.next().value);
// [0, "a"]
console.log(iterator.next().value);
// [1, "b"]
console.log(iterator.next().value);
// [2, "c"]
Array.prototype.every()
如果數(shù)組中的每個(gè)元素都滿(mǎn)足測(cè)試函數(shù)悠轩,則返回 true间狂,否則返回 false。
Array.prototype.some()
如果數(shù)組中至少有一個(gè)元素滿(mǎn)足測(cè)試函數(shù)火架,則返回 true鉴象,否則返回 false。
Array.prototype.filter()
將所有在過(guò)濾函數(shù)中返回 true 的數(shù)組元素放進(jìn)一個(gè)新數(shù)組中并返回何鸡。
Array.prototype.find()
找到第一個(gè)滿(mǎn)足測(cè)試函數(shù)的元素并返回那個(gè)元素的值纺弊,如果找不到,則返回 undefined音比。
語(yǔ)法:
arr.find(callback[, thisArg])
參數(shù):
- callback
在數(shù)組每一項(xiàng)上執(zhí)行的函數(shù)俭尖,接收 3 個(gè)參數(shù): - element
當(dāng)前遍歷到的元素。 - index
當(dāng)前遍歷到的索引洞翩。 - array
數(shù)組本身稽犁。 - thisArg 可選
可選,指定 callback 的 this 參數(shù)骚亿。
返回值:
當(dāng)某個(gè)元素通過(guò) callback 的測(cè)試時(shí)已亥,返回?cái)?shù)組中的一個(gè)值,否則返回 undefined
function isBigEnough(element) {
return element >= 15;
}
[12, 5, 8, 130, 44].find(isBigEnough); // 130
Array.prototype.findIndex()
找到第一個(gè)滿(mǎn)足測(cè)試函數(shù)的元素并返回那個(gè)元素的索引来屠,如果找不到虑椎,則返回 -1。
Array.prototype.keys()
返回一個(gè)數(shù)組迭代器對(duì)象俱笛,該迭代器會(huì)包含所有數(shù)組元素的鍵捆姜。
Array.prototype.map()
返回一個(gè)由回調(diào)函數(shù)的返回值組成的新數(shù)組。
Array.prototype.reduce()
從左到右為每個(gè)數(shù)組元素執(zhí)行一次回調(diào)函數(shù)迎膜,并把上次回調(diào)函數(shù)的返回值放在一個(gè)暫存器中傳給下次回調(diào)函數(shù)泥技,并返回最后一次回調(diào)函數(shù)的返回值。
Array.prototype.reduceRight()
從右到左為每個(gè)數(shù)組元素執(zhí)行一次回調(diào)函數(shù)磕仅,并把上次回調(diào)函數(shù)的返回值放在一個(gè)暫存器中傳給下次回調(diào)函數(shù)珊豹,并返回最后一次回調(diào)函數(shù)的返回值簸呈。
4.2.4 泛型方法
泛型方法是非標(biāo)準(zhǔn),并且已棄用店茶,有可能不久就會(huì)移除蜕便。 需注意的是此方法同時(shí)有跨瀏覽器問(wèn)題. 但是 Github上有可用的shim。
有時(shí)我們會(huì)希望在字符串或其他類(lèi)數(shù)組對(duì)象上使用數(shù)組所提供的方法(如函數(shù)的 arguments)贩幻。此時(shí)你可以把一個(gè)字符串作為一個(gè)字符數(shù)組來(lái)看待(也就是說(shuō)轿腺,把非數(shù)組以某種方式看成是一個(gè)數(shù)組)。比如丛楚,可以用下面的方法來(lái)檢查變量 str 中的字符是否都是字母:
function isLetter(character) {
return character >= 'a' && character <= 'z';
}
if (Array.prototype.every.call(str, isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
這種方法能夠行得通吃溅,但不夠簡(jiǎn)潔,JavaScript 1.6 中引入了一個(gè)泛型化的簡(jiǎn)寫(xiě)形式:
if (Array.every(str, isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
這些并不屬于 ECMAScript 標(biāo)準(zhǔn)鸯檬,也不能在非 Gecko 瀏覽器中使用。你可以用標(biāo)準(zhǔn)方法 Array.from()來(lái)替代上面的寫(xiě)法螺垢, from 方法可以將一個(gè)對(duì)象轉(zhuǎn)換為真正的數(shù)組(雖然老的瀏覽器可能不支持):
if (Array.from(str).every(isLetter)) {
console.log("The string '" + str + "' contains only letters!");
}
5. Array實(shí)例對(duì)象的屬性與方法
我們用Object.getOwnPropertyNames()方法獲取Array實(shí)例對(duì)象的所有屬性與方法喧务。
var arr = new Array(1, '2', undefined);
Object.getOwnPropertyNames(arr);
// ["0", "1", "2", "length"]
發(fā)現(xiàn)數(shù)組每一項(xiàng)的index均為其屬性,另外還一個(gè)屬性length表示其長(zhǎng)度枉圃。(再次同樣有JS原生引用類(lèi)型解析1-Object類(lèi)型末尾關(guān)于_proto_的疑惑)功茴。
參考
MDN_Array
W3schoocl-JavaScript Array 對(duì)象
BOOK-《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》第5章