将类数组对象转换为数组
什么是类似数组的对象?
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
有关详细分析,请参阅阵列是对象 。