將類陣列物件轉換為陣列
什麼是類似陣列的物件?
JavaScript 具有類似陣列的物件,它是具有 length 屬性的陣列的 Object 表示。例如:
var realArray = ['a', 'b', 'c'];
var arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
類似陣列的物件的常見示例是函式中的 arguments
物件以及從 document.getElementsByTagName
或 document.querySelectorAll
等方法返回的 HTMLCollection
或 NodeList
物件。
但是,Arrays 和類似 Array 的物件之間的一個關鍵區別是,類似於 Array 的物件繼承自 Object.prototype
而不是 Array.prototype
。這意味著類似陣列的物件無法訪問常見的陣列原型方法, 如 forEach()
, push()
, map()
, filter()
和 slice()
:
var parent = document.getElementById('myDropdown');
var desiredOption = parent.querySelector('option[value="desired"]');
var domList = parent.children;
domList.indexOf(desiredOption); // Error! indexOf is not defined.
domList.forEach(function() {
arguments.map(/* Stuff here */) // Error! map is not defined.
}); // Error! forEach is not defined.
function func() {
console.log(arguments);
}
func(1, 2, 3); // → [1, 2, 3]
在 ES6 中將類似陣列的物件轉換為陣列
Array.from
:
Version >= 6
const arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
arrayLike.forEach(value => {/* Do something */}); // Errors
const realArray = Array.from(arrayLike);
realArray.forEach(value => {/* Do something */}); // Works
for...of
:
Version >= 6
var realArray = [];
for(const element of arrayLike) {
realArray.append(element);
}
- 傳播運算子:
Version >= 6
[...arrayLike]
Object.values
:
Version >= 7
var realArray = Object.values(arrayLike);
Object.keys
:
Version >= 6
var realArray = Object
.keys(arrayLike)
.map((key) => arrayLike[key]);
在≤ES5 中將類陣列物件轉換為陣列
像這樣使用 Array.prototype.slice
:
var arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
var realArray = Array.prototype.slice.call(arrayLike);
realArray = [].slice.call(arrayLike); // Shorter version
realArray.indexOf('Value 1'); // Wow! this works
你也可以使用 Function.prototype.call
直接在類似陣列的物件上呼叫 Array.prototype
方法,而無需轉換它們:
Version >= 5.1
var domList = document.querySelectorAll('#myDropdown option');
domList.forEach(function() {
// Do stuff
}); // Error! forEach is not defined.
Array.prototype.forEach.call(domList, function() {
// Do stuff
}); // Wow! this works
你也可以使用 [].method.bind( arrayLikeObject )
借用陣列方法並將它們放到你的物件上:
Version >= 5.1
var arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
arrayLike.forEach(function() {
// Do stuff
}); // Error! forEach is not defined.
[].forEach.bind(arrayLike)(function(val){
// Do stuff with val
}); // Wow! this works
轉換期間修改專案
在 ES6 中,在使用 Array.from
時,我們可以指定一個 map 函式,該函式返回正在建立的新陣列的對映值。
Version >= 6
Array.from(domList, element => element.tagName); // Creates an array of tagName's
有關詳細分析,請參閱陣列是物件 。