JavaScript 将非数组对象转换为数组的多种方法详解

作者:拾光时间:2026-10-22 13:22:48浏览:634

本文汇总了JavaScript中将非数组对象转换为数组的几种核心方法。重点解析利用Array.prototype.slice.call处理类数组对象,使用Array.from兼容可迭代对象,以及通过展开运算符([...obj])和Object.values()实现转换的技巧。同时对比了for...of、forEach与for...in的遍历差异,帮助开发者根据具体场景选择最优方案。

前言

前言

本文主要梳理了JavaScript中将非数组对象转换为数组的常见实现方式,供读者参考学习。以下内容将逐一展开详细介绍。

利用 Array.prototype.slice.call 进行转换

利用 Array.prototype.slice.call 进行转换

该方法适用于将类数组对象转换为真正的数组。所谓类数组对象,是指具备 length 属性以及数字索引属性的对象。

转换后数组的长度由原对象的 length 属性值决定。若索引值大于 length,或对象中存在非索引属性,这些内容均不会被包含在返回的数组中。

具体示例如下


let obj = {
 '0': 3,
 '1': 13,
 '2': 23,
 '3': 33,
 'length': 3,
 'name': 330
}
let arr = Array.prototype.slice.call(obj)
// [3, 13, 23]

更简洁的写法为 [].slice.call(obj)

使用 Array.from 方法

使用 Array.from 方法

Array.from 能够将类数组对象以及可迭代对象(Iterable)转换为数组。

前文已介绍类数组对象,那么什么是可迭代对象呢?

  • Array、Set、Map 以及字符串均属于可迭代对象(注意:WeakMap 和 WeakSet 不属于可迭代对象)。
  • 字符串被定义为可迭代对象,这有助于解决字符编码处理相关的问题。
  • 这些对象内部都拥有默认的迭代器,即具备 Symbol.iterator 属性。
  • 可以使用 for...of 循环来遍历这些对象。
  • 所有通过生成器(Generator)创建的迭代器都是可迭代对象。
  • document.getElementsByTagName("div") 返回的是可迭代对象,但它并非数组类型。 Array.isArray(document.getElementsByTagName('div')) 返回 false

通过生成器手动创建可迭代对象


let obj = {
 '0': 3,
 '1': 13,
 '2': 23,
 '3': 33
}

function *createIterator(obj){
 for(let value in obj){
  yield obj[value]
 }
}

let iterator = createIterator(obj)
let arr = Array.from(iterator)
// [3, 13, 23, 33]

改造对象本身,使其具备可迭代能力

默认情况下,开发者自定义的对象是不可迭代的。但如果为 Symbol.iterator 属性赋值一个生成器,该对象即可变为可迭代对象。


let obj = {
 '0': 3,
 '1': 13,
 '2': 23,
 '3': 33
}

obj[Symbol.iterator] = function* () {
 for(let value in this){
  yield this[value]
 }
}

let arr = Array.from(obj)
// [3, 13, 23, 33]

判断对象是否为可迭代对象的方法


typeof obj[Symbol.iterator] === 'function'

延伸讨论:for...of、forEach 与 for...in 的区别

延伸讨论:for...of、forEach 与 for...in 的区别

for...of 用于遍历可迭代对象,支持的类型包括 Array、Set、Map 和字符串。

此外,Array、Set 和 Map 都内置了 forEach 方法。

另外,NodeList 虽然不属于 Array、Set 或 Map,但它是可迭代对象,可以使用 for...of 进行遍历。

值得注意的是,使用 for...of 循环对象时,可以通过 break 语句提前终止循环;而 forEach 方法不支持提前跳出循环。

for...in 用于遍历对象的可枚举属性,包括原型链上的属性,且不保证遍历顺序。

若需仅遍历对象自身的可枚举属性,应使用 hasOwnProperty() 方法来判断属性是否属于对象自身。

Object.getOwnPropertyNames(obj) ,该方法返回对象自身的所有属性名,包括可枚举和不可枚举属性。

既然话题已展开,再补充一点:Object.assign() 方法会将一个或多个源对象中所有可枚举属性的值复制到目标对象。

使用展开运算符 [...obj]

使用展开运算符 [...obj]

展开运算符可以将可迭代对象转换为数组。

例如, [...'obj'] 返回 ["o", "b", "j"]

字符串去重示例

[...new Set('objobj')]

使用 Object.values 方法

使用 Object.values 方法

默认情况下,开发者定义的对象是不可迭代的,但可以通过提供返回迭代器的方法来实现转换。

  • entries() 方法
  • values() 方法
  • keys() 方法

通过调用上述方法,可以获取相关的数组数据。

与类数组对象依赖 length 属性不同,Object.values(obj) 返回的是对象自身可枚举属性值的集合。


let obj = {
 '0': 3,
 '1': 13,
 '2': 23,
 '3': 33
}
let arr = Object.values(obj) // [3, 13, 23, 33]

字符串与数组的关系

字符串与数组的关系

在某种程度上,可以将字符串视为字符串数组。

字符串和数组都具备 length 属性。

两者都拥有 concat() 、indexOf()、includes() 以及 slice() 等方法。

需要注意的是,string 类型没有方法可以原地修改其内容,所有相关操作均返回新的字符串。

string 类型还提供了一个 repeat() 方法,用于创建指定数量的字符串副本。

总结

总结

以上就是本文介绍的全部内容,希望这些关于JavaScript对象转数组的方法对大家的编程学习或工作有所帮助。如有疑问,欢迎留言交流,感谢支持。

作者最新文章