Array對象 創建數組: 數組字面量:var arr1 = [1,2,3]; Array構造函數1:var arr2 = new Array(1,2,3); //[1,2,3] Array構造函數2:var arr3 = new Array(3); var arr3 = new Array(‘3’ ...
Array對象
本文參考MDN做的詳細整理,方便大家參考[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
創建數組:
- 數組字面量:var arr1 = [1,2,3];
- Array構造函數1:var arr2 = new Array(1,2,3); //[1,2,3]
- Array構造函數2:var arr3 = new Array(3); var arr3 = new Array(‘3’); var arr3 = new Array('ol');
- 錯誤寫法:var arr3 = new Array(3.2); var arr3 = new Array(-3);
- 例:var arr5 = new Array(50) 返回的數組arr5的成員都是空位,雖然讀取的時候返回undefined,但實際上該位置沒有任何值,雖然可以取到length屬性,但是取不到鍵名( 0 in arr5; //false )
向 Array 構造函數傳入一個在 0 到 232-1 之間的整數,將返回一個以此為長度的數組對象。通過 length 屬性可以訪問這個值。如果傳入的唯一參數不是字元串且不是有效的整數數值,則拋出 RangeError 異常。
Array作為構造函數,行為很不一致。因此,不建議使用它生成新數組,直接使用數組字面量是更好的做法。
數組的長度及其中元素的類型都是不固定的。因為數組的長度可讀可寫,有時數組中的元素也不是在連續的位置,所以JavaScript 數組不一定是密集的。通常情況下,這是一些方便的特性;如果這些特性不適用於你的特定使用場景,你可以考慮使用固定類型數組
JavaScript 中訪問合法的屬性名可以用"."或者"[ ]",但是訪問非法的屬性x只能用"[ 'x' ]"。比如說,如果你有一個名為 ‘3d’ 的屬性,它只能通過方括弧的形式進行訪問['3d']。
當你在 array 上使用一個合法的數組下標,而且該下標超出了當前數組的大小的時候,引擎會根據其值自動增大 length,而減小 array 的length屬性會刪掉超出的元素。
Array的屬性
Array.length
Array 構造函數的 length 屬性,其值為1。
允許為所有數組對象附加屬性。
Array.prototype[@@unscopables] 只有Firefox支持
Symbol屬性 @@unscopable 包含了所有 ES2015 (ES6) 中新定義的且並未被更早的 ECMAScript 標準收納的屬性名。這些屬性並不包含在 with 語句綁定的環境中
語法:arr[Symbol.unscopables]
Array的靜態方法
假如一個變數obj是數組則返回true,否則返回false。下麵是通用方法:
var isArray = function(a) {
return Array.isArray ? Array.isArray(a) : Object.prototype.toString.call(a) === '[object Array]';
};
Array.from( arrayLike[, mapFn[, thisArg]] ) ES6
將一個類數組對象或可遍歷對象轉換成真正的數組,返回數組的的實例。在 ES6 中, Class 語法允許我們為內置類型(比如 Array)和自定義類新建子類(比如叫 SubArray)。這些子類也會繼承父類的靜態方法,比如 SubArray.from(),調用該方法後會返回子類 SubArray 的一個實例,而不是 Array 的實例。
- arrayLike想要轉換成真實數組的類數組對象或可遍歷對象。
- mapFn可選參數,如果指定了該參數,則最後生成的數組會經過該函數的加工處理後再返回。
- thisArg可選參數,執行 mapFn 函數時 this 的值。
Array.of() ES6
將它的任意類型的多個參數放在一個數組裡並返回該數組。
Polyfill 如果原生不支持的話,在其他代碼之前執行以下代碼會創建 Array.of() 。
if (!Array.of) {
Array.of = function() {
return Array.prototype.slice.call(arguments);
};
}
Array的實例屬性:
Array.prototype.constructor
所有的數組實例都繼承了這個屬性,它的值就是 Array,表明瞭所有的數組都是由 Array 構造出來的。
Array的實例方法:
下麵的這些方法會改變調用它們的對象自身的值:
刪除數組的最後一個元素,並返回這個元素。
Array.prototype.push(element1, ..., elementN)
在數組的末尾增加一個或多個元素,並返回數組的新長度length。
- push 方法有意具有通用性。該方法和 call() 或 apply() 一起使用時,可應用在數組和類似數組的對象上。push 方法根據 length 屬性來決定從哪裡開始插入給定的值。如果 length 不能被轉成一個數值,則插入的元素索引為 0,包括 length 不存在時。當 length 不存在時,將會創建它。
- 註意:唯一的原生類數組對象是String,它並不適用該方法,因為字元串是不可改變的。
- 合併兩個數組a和b,可以用concat方法,也可以用a.push.apply(a,b);
- push和pop結合使用,就構成了“後進先出”的棧結構(stack)
- push和shift結合使用,就構成了“先進先出”的隊列結構(queue)
顛倒數組中元素的排列順序,即原先的第一個變為最後一個,原先的最後一個變為第一個。
移除索引為 0 的元素(即第一個元素),並返回被移除的元素,其他元素的索引值隨之減 1。如果 length 屬性的值為 0 (長度為 0),則返回 undefined。
shift 方法並不局限於數組:該方法亦可通過 call 或 apply 作用於對象上。對於不包含 length 屬性的對象,將添加一個值為 0 的 length 屬性。
Array.prototype.unshift(element1, ..., elementN)
在數組的開頭增加一個或多個元素,並返回數組的新的 length 值。
- unshift 方法會在調用它的類數組(array-like)對象的開始位置插入給定的參數。
- unshift 特意被設計成具有通用性;這個方法能夠通過 call 或 apply 方法作用於類似數組的對象上。不過對於沒有 length 屬性(代表從0開始的一系列連續的數字屬性的最後一個)的對象,調用該方法可能沒有任何意義
Array.prototype.sort([compareFunction])
對數組的元素做原地的排序,並返回這個數組。 sort 可能不是穩定的。預設按照字元串的Unicode碼位點(code point)排序。
如果指明瞭參數compareFunction ,那麼數組會按照調用該函數的返回值排序。記 a 和 b 是兩個將要被比較的元素:
- 如果 compareFunction(a, b) 小於 0 ,那麼 a 會被排列到 b 之前;
- 如果 compareFunction(a, b) 等於 0 , a 和 b 的相對位置不變。備註: ECMAScript 標準並不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本);
- 如果 compareFunction(a, b) 大於 0 , b 會被排列到 a 之前。
- compareFunction(a, b) 必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。
Array.prototype.splice(start, deleteCount[, item1[, item2[, ...]]])
在任意的位置start給數組添加、刪除、替換任意個元素。總是返回(由被刪除的元素組成的)一個數組。如果只刪除了一個元素,則返回只包含一個元素的數組。如果沒有刪除元素,則返回空數組。如果只提供第一個參數,等同於將原數組在指定位置拆分成兩個數組。如果只要插入元素,可將第二個參數設為0
- start 從數組的哪一位開始修改內容。如果超出了數組的長度,則從數組末尾開始添加內容;如果是負值,則表示從數組末位開始的第幾位。
- deleteCount 整數,表示要移除的數組元素的個數。如果 deleteCount 是 0,則不移除元素。這種情況下,至少應添加一個新元素。如果 deleteCount 大於start 之後的元素的總數,則從 start 後面的元素都將被刪除(含第 start 位)。
- itemN 要添加進數組的元素。如果不指定,則 splice() 只刪除數組元素。
Array.prototype.copyWithin() ES6
在數組內部,將一段元素序列拷貝到另一段元素序列上,覆蓋原有的值。
將數組中指定區間的所有元素的值,都替換成某個固定的值。
下麵的這些方法絕對不會改變調用它們的對象自身的值,只會返回一個新的數組或者返回一個其它的期望值:
將傳入的數組或非數組值與原數組合併,組成一個新的數組並返回,它們是按照順序放入這個新數組的
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
concat 方法並不修改調用它的對象(this 指向的對象) 和參數中的各個數組本身的值,而是將他們的每個元素拷貝一份放在組合成的新數組中,原數組中的元素有兩種被拷貝的方式:
- 對象引用(非對象直接量):concat 方法會複製對象引用放到組合的新數組裡,原數組和新數組中的對象引用都指向同一個實際的對象,所以,當實際的對象被修改時,兩個數組也同時會被修改.
將數組中所有的數組元素轉換成字元串,再用一個分隔符將這些字元串連接起來。如果元素是undefined 或者null, 則會轉化成空字元串。
var str = arr.join( [separator = ','] );
參數separator 可選,用於指定連接每個數組元素的分隔符。分隔符會被轉成字元串類型;如果省略的話,預設為一個逗號。如果 seprator 是一個空字元串,那麼數組中的所有元素將被直接連接。
Array.prototype.slice( [begin[,end]] )
淺複製(shallow copy)數組的一段到一個新的數組中,並返回這個新數組。範圍:從begin到end(不含end)
- 可選參數begin 從該索引處開始複製(省略則為預設為0),若為負數,表示從數組的倒數位置開始(最後一個是-1)
- 可選參數end 指定結束複製位置的索引,省略則表示提取從begin開始到末尾。
- 若元素為對象引用(非對象直接量):會複製對象引用放到新數組裡,原數組和新數組中的對象引用都指向同一個實際的對象,所以,當實際的對象被修改時,兩個數組也同時會被修改.
- 若元素為字元串和數字(是原始值,而不是包裝原始值的 String 和 Number 對象): 會複製字元串和數字的值放到新數組裡.
- slice 方法可以用來將一個類數組(Array-like)對象/集合轉換成一個數組。Array.prototype.slice.call(arguments) 或 [].slice.call(arguments)
Array 對象覆蓋了 Object.prototype.toString() 方法。對於數組對象,toString 方法返回一個字元串,該字元串由數組中的每個元素的 toString() 返回值經調用 join() 方法連接(由逗號隔開)組成。當一個數組被作為文本值或者進行字元串連接操作時,將會自動調用其 toString 方法。
Array.prototype.toLocaleString()
返回一個由所有數組元素組合而成的本地化後的字元串。遮蔽了原型鏈上的 Object.prototype.toLocaleString() 方法。數組中的元素將使用各自的 toLocaleString 方法轉成字元串,這些字元串將使用一個特定語言環境的字元串(例如一個逗號 ",")隔開:
- Object: Object.prototype.toLocaleString()
- Number: Number.prototype.toLocaleString()
- Date: Date.prototype.toLocaleString()
Array.prototype.indexOf(searchElement[, fromIndex = 0]) IE9
返回數組中第一個與指定值searchElement相等(使用嚴格相等)的元素的索引,如果找不到這樣的元素,則返回 -1。
參數fromIndex 開始查找的位置,其預設值為0。如果該索引值大於或等於數組長度,意味著不會在數組裡查找,返回-1。可以為負值。
Array.prototype.lastIndexOf(searchElement[, fromIndex = arr.length - 1]) IE9
返回數組中最後一個(從右邊數第一個)與指定值相等(使用嚴格相等)的元素的索引,如果找不到這樣的元素,則返回 -1。從數組的後面向前查找,從 fromIndex 處開始,若大於等於預設值arr.length - 1,即在整個數組中查找。如果為負值,將其視為從數組末尾向前的偏移。即使該值為負,數組仍然會被從後向前查找。如果該值為負時,其絕對值大於數組長度,則方法返回 -1,即數組不會被查找。
Array.prototype.includes() ES7
判斷當前數組是否包含某指定的值,如果是返回 true,否則返回 false。
遍歷方法
在下麵的眾多遍歷方法中,有很多方法都需要指定一個回調函數callback作為參數。在回調函數執行之前,數組的長度會被緩存在某個地方,所以,如果你在回調函數中為當前數組添加了新的元素,那麼那些新添加的元素是不會被遍歷到的。此外,如果在回調函數中對當前數組進行了其它修改,比如改變某個元素的值或者刪掉某個元素,那麼隨後的遍歷操作可能會受到未預期的影響。總之,不要嘗試在遍歷過程中對原數組進行任何修改
Array.prototype.forEach(callback[, thisArg]) IE9
為數組中的每個元素執行一次回調函數。
- forEach 方法按升序為數組中含有效值的每一項執行一次callback 函數,那些已刪除(使用delete方法等情況)或者從未賦值的項將被跳過(但不包括哪些值為 undefined 的項)。
- forEach 遍歷的範圍在第一次調用 callback 前就會確定。調用forEach 後添加到數組中的項不會被 callback 訪問到。如果已經存在的值被改變,則傳遞給 callback 的值是 forEach 遍歷到他們那一刻的值。已刪除的項不會被遍歷到。
- 沒有辦法中止或者跳出 forEach 迴圈,除了拋出一個異常。如果你需要這樣,使用forEach()方法是錯誤的,你可以用一個簡單的迴圈作為替代。如果您正在測試一個數組裡的元素是否符合某條件,且需要返回一個布爾值,那麼可使用 Array.every 或 Array.some。
callback ( currentValue, index, array )回調函數,接收三個參數:currentValue數組當前項的值,index當前項的索引,array數組對象本身。
thisArg 可選參數。用來當作callback 函數內this的值的對象。如果 thisArg 值為 undefined 或 null,函數的 this 值取決於當前執行環境是否為嚴格模式(嚴格模式下為 undefined,非嚴格模式下為全局對象)。
Array.prototype.every(callback[, thisArg]) IE9
如果數組中的每個元素都滿足測試函數,則返回 true,否則,在遇到第一個不滿足測試函數時就立即返回 false。
callback ( currentValue, index, array ) (會跳過空元素)只會為那些已經被賦值的索引調用,不會為那些被刪除或從來沒被賦值的索引調用。
- every 不會改變原數組。
- every 遍歷的元素範圍在第一次調用 callback 之前就已確定了。在調用 every 之後添加到數組中的元素不會被callback 訪問到。
- 如果數組中存在的元素被更改,則他們傳入 callback 的值是 every 訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。
Array.prototype.some(callback[, thisArg]) IE9
如果數組中至少有一個元素滿足測試函數,直到找到第一個滿足callback時才立即返回 true,否則返回 false。其它和every方法一致
Array.prototype.filter(callback[, thisArg]) IE9
將所有在過濾函數中 callback(element, index, array) 中返回 true或等價於 true 的值的數組元素element放進一個新數組中並返回。同forEach、every、some一樣,filter方法也會會跳過空值,開始遍歷時,也確定了範圍。
Array.prototype.map(callback[, thisArg]) IE9
返回一個由原數組中的每個元素調用一個指定方法後的返回值組成的新數組。
map 方法會給原數組中的每個元素都按順序調用一次 callback 函數。callback 每次執行後的返回值組合起來形成一個新數組。 map方法也會跳過空值,其它同以上方法一樣。
["1", "2", "3"].map(parseInt);
// 你可能覺的會是[1, 2, 3] // 但實際的結果是 [1, NaN, NaN]
map方法在調用callback函數時,會自動給它傳遞三個參數:當前正在遍歷的元素, 元素索引, 原數組本身.第三個參數parseInt會忽視, 但第二個參數不會,也就是說,parseInt把傳過來的索引值當成進位數來使用.從而返回了NaN.這時應該使用自定義回調函數來包裝function callback(element){ return parseInt(element,10); }
Array.prototype.reduce(callback,[initialValue]) IE9
從左到右為每個數組元素執行一次回調函數,並把上次回調函數的返回值放在一個暫存器中傳給下次回調函數,並返回最後一次回調函數的返回值。即:接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始合併,最終為一個值。它也會跳過空元素
callback(previousValue,currentValue,index,array)
- previousValue 上一次調用回調返回的值,或者是提供的初始值(initialValue)
- currentValue 數組中當前被處理的元素
-
index 當前元素在數組中的索引
-
array 調用 reduce 的數組
initialValue 作為第一次調用 callback 的第一個參數(提供的初始值)
- 回調函數第一次執行時,previousValue 和 currentValue 可以是一個值,如果 initialValue 在調用 reduce 時被提供,那麼第一個 previousValue 等於 initialValue ,並且currentValue 等於數組中的第一個值;如果initialValue 未被提供,那麼previousValue 等於數組中的第一個值,currentValue等於數組中的第二個值。
- 如果數組為空並且沒有提供initialValue, 會拋出TypeError 。
- 如果數組僅有一個元素(無論位置如何)並且沒有提供initialValue, 或者有提供initialValue但是數組為空,那麼此唯一值將被返回並且callback不會被執行。
Array.prototype.reduceRight() IE9
從右到左為每個數組元素執行一次回調函數,並把上次回調函數的返回值放在一個暫存器中傳給下次回調函數,並返回最後一次回調函數的返回值。其它同reduce方法
Array.prototype.entries() ES6 IE無
返回一個數組迭代器對象Array Iterator ,該迭代器對象會包含所有數組元素的鍵值對。
Array.prototype.find(callback[, thisArg]) ES6 IE無
找到第一個滿足測試函數的元素並返回那個元素的值,如果找不到,則返回 undefined。
- 調用callback函數帶有3個參數:當前元素的值、當前元素的索引,以及數組本身
- find方法對數組中的每一項元素執行一次callback 函數,直至有一個callback返回true。當找到了這樣一個元素後,該方法會立即返回這個元素的值,否則返回undefined
- callback回調函數也會跳過空值,其它同every、some等方法
Array.prototype.findIndex() ES6 只有Firefox支持
找到第一個滿足測試函數的元素並返回那個元素的索引,如果找不到,則返回 -1。
Array.prototype.keys() ES6 IE無
返回一個數組迭代器對象,該迭代器會包含所有數組元素的鍵。索引迭代器會包含那些沒有對應元素的索引
迭代器的執行原理
var arr = ["a", "b", "c"];
var iterator = arr.keys();
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Array.prototype.values() ES6 只有Firefox、Safari支持
返回一個新的 Array Iterator 迭代器對象,該迭代器會包含所有數組元素的值。
使用 for...of 迴圈進行迭代
var arr = ['w', 'y', 'k', 'o', 'p'];
var eArr = arr.values();
您的瀏覽器必須支持 for..of 迴圈,以及 let —— 將變數作用域限定在 for 迴圈中
for (let letter of eArr) {
console.log(letter);
}
另一種迭代方式
var arr = ['w', 'y', 'k', 'o', 'p'];
var eArr = arr.values();
console.log(eArr.next().value); // w
console.log(eArr.next().value); // y
console.log(eArr.next().value); // k
console.log(eArr.next().value); // o
console.log(eArr.next().value); // p
Array.prototype[@@iterator]() ES6 IE、Safari無
數組的@@iterator屬性和 values() 屬性的初始值均為同一個函數對象。@@iterator屬性返回數組的 iterator 方法,預設情況下與 values() 返回值相同
var arr = ['w', 'y', 'k', 'o', 'p'];
var eArr = arr[Symbol.iterator]();