ES6Array.from转换类数组方法详解
在ES6中,`Array.from()`方法是转换类数组对象和可迭代对象的利器。它不仅解决了传统方法(如`Array.prototype.slice.call()`)的语义不清晰和适用范围窄的问题,还提供了更强大、更灵活的数组创建方式。本文将深入探讨`Array.from()`的语法、功能和优势,例如,支持`arguments`、`NodeList`、`Set`、`Map`和字符串等多种数据类型,以及内置的映射功能,在转换的同时处理元素。此外,文章还将对比`Array.from()`与展开运算符(`...`)的区别,并通过实际案例,展示其在生成数字序列、处理DOM集合、克隆数组、从字符串创建字符数组等高级应用场景中的妙用,帮助开发者更好地理解和运用这一ES6的重要特性,提升代码的可读性和效率。
Array.from() 是 ES6 中用于将类数组对象或可迭代对象转换为新数组的方法。其语法为 Array.from(arrayLike, mapFn, thisArg),其中 arrayLike 是必填参数,表示要转换的对象;mapFn 和 thisArg 为可选参数,分别用于元素映射和指定 this 上下文。1. 它解决了传统使用 Array.prototype.slice.call() 转换类数组对象时语义不清晰、适用范围窄的问题;2. 支持类数组对象(如 arguments、NodeList)和可迭代对象(如 Set、Map、字符串);3. 提供内置映射功能,在转换过程中即可处理元素;4. 相较于展开运算符(...),Array.from 更适用于非可迭代的类数组对象,并能在转换时进行映射;5. 高级应用包括生成数字序列、处理 DOM 集合、克隆数组、从字符串创建字符数组等场景。它提升了代码的语义化、可读性和灵活性,是处理数据集合的重要工具。
ES6 中的 Array.from
方法是用来将类数组对象或可迭代对象转换成一个真正的数组实例。它的出现,极大地简化了我们处理那些“看起来像数组但又不是数组”的数据结构的流程,提供了一种更语义化、更灵活的转换方式。

解决方案
Array.from()
静态方法从一个类数组或可迭代对象创建一个新的、浅拷贝的数组实例。它的基本语法是:
Array.from(arrayLike, mapFn, thisArg)
arrayLike
: 这是一个必需的参数,可以是类数组对象(拥有一个length
属性和可索引元素,比如arguments
对象或NodeList
)或者可迭代对象(比如Set
、Map
、String
)。mapFn
(可选): 一个映射函数,新数组中的每个元素都会经过这个函数的处理。这使得我们可以在转换的同时对元素进行操作,非常方便。thisArg
(可选): 执行mapFn
时使用的this
值。
举几个例子,你会发现它用起来真的非常直观:

// 1. 转换 arguments 对象 function toArray() { // arguments 是一个类数组对象 const args = Array.from(arguments); console.log(args); // 比如传入 (1, 2, 3) 会得到 [1, 2, 3] } toArray(1, 2, 3); // 2. 转换 NodeList (例如从 DOM 查询结果) // 假设 HTML 中有多个 div 元素 // const divs = document.querySelectorAll('div'); // 这是一个 NodeList,不是真正的数组 // const divArray = Array.from(divs); // console.log(divArray); // 现在你可以对 divArray 使用所有数组方法了,比如 forEach, map, filter // 3. 转换字符串 (字符串是可迭代的) const str = "hello"; const charArray = Array.from(str); console.log(charArray); // ['h', 'e', 'l', 'l', 'o'] // 4. 结合映射函数 (mapFn) // 生成一个从 0 到 4 的数组,并每个元素翻倍 const numbers = Array.from({ length: 5 }, (v, i) => i * 2); console.log(numbers); // [0, 2, 4, 6, 8] // 5. 转换 Set 或 Map const mySet = new Set([1, 2, 3, 3, 4]); const setArray = Array.from(mySet); console.log(setArray); // [1, 2, 3, 4] const myMap = new Map([['a', 1], ['b', 2]]); const mapArray = Array.from(myMap); console.log(mapArray); // [['a', 1], ['b', 2]]
Array.from
的强大之处在于它能处理任何具有 Symbol.iterator
属性的对象(即可迭代对象),以及任何具有 length
属性的对象(即类数组对象),这覆盖了我们日常开发中绝大部分需要转换的场景。
为什么我们需要Array.from?它解决了什么痛点?
在 Array.from
出现之前,我们处理类数组对象,比如 arguments
或者 document.querySelectorAll()
返回的 NodeList
,通常会用一些相对“古老”或者说不那么直观的方法。最常见的就是 Array.prototype.slice.call()
:

// 以前我们可能会这么做 function oldSchoolToArray() { const args = Array.prototype.slice.call(arguments); console.log(args); } oldSchoolToArray(10, 20, 30); // 或者 // const divs = document.querySelectorAll('div'); // const divArray = Array.prototype.slice.call(divs);
这种写法虽然有效,但总感觉有点别扭,对吧?尤其是对于刚接触 JavaScript 的开发者来说,Array.prototype.slice.call(arguments)
这种链式调用和 call
方法的使用,理解起来门槛稍微高一些。它本质上是借用了 Array.prototype
上的 slice
方法,并强制将 arguments
对象的 this
上下文绑定到 slice
方法上,从而模拟出数组切片的效果,间接实现了转换。
在我看来,Array.from
解决了几个核心痛点:
- 语义化和可读性:
Array.from
的名字本身就非常清晰地表达了它的意图——“从...创建一个数组”。这比slice.call
这种略显“黑魔法”的写法要好理解得多。代码的可读性提升了,维护起来自然也更轻松。 - 更广泛的适用性:
slice.call
只能处理那些“长得像数组”的对象(有length
属性和可索引项),但对真正的可迭代对象(比如Set
、Map
)就无能为力了。而Array.from
既能处理类数组,也能处理所有可迭代对象,这让它成为了一个更通用的工具。 - 内置的映射能力:
Array.from
的第二个参数mapFn
是一个非常实用的功能。它允许你在转换的同时对每个元素进行处理,这在很多场景下能省去一次额外的map
调用。比如,你想把一个NodeList
转换成数组,并且只取每个元素的id
,用Array.from
一步到位:// const ids = Array.from(document.querySelectorAll('div'), div => div.id);
这比先转换再
map
要简洁不少。
所以,Array.from
不仅仅是语法糖,它更是对 JavaScript 数组操作能力的一次重要补强和现代化。它让我们的代码更干净、更易懂,也更强大。
Array.from与展开运算符(Spread Operator)有什么区别?何时选择谁?
展开运算符(...
)也是 ES6 引入的一个非常强大的特性,它也能将可迭代对象转换成数组,或者用于数组的合并、复制等。例如:
// 使用展开运算符转换字符串 const strSpread = [...'hello']; console.log(strSpread); // ['h', 'e', 'l', 'l', 'o'] // 转换 Set const mySetSpread = new Set([1, 2, 3]); const setArraySpread = [...mySetSpread]; console.log(setArraySpread); // [1, 2, 3] // 转换 NodeList // const divsSpread = [...document.querySelectorAll('div')];
看起来它们的功能有些重叠,那我们到底该如何选择呢?这里有一些关键的区别和考量:
处理对象类型:
- 展开运算符 (
...
):只能用于可迭代对象。如果一个对象没有实现Symbol.iterator
接口(例如一个纯粹的类数组对象{0: 'a', 1: 'b', length: 2}
),展开运算符就无法直接将其转换为数组。 Array.from()
:既可以处理可迭代对象,也可以处理类数组对象(只要有length
属性和可索引项)。这是它比展开运算符更灵活的地方。
const myCustomArrayLike = { 0: 'apple', 1: 'banana', length: 2 }; // const arr1 = [...myCustomArrayLike]; // 报错:myCustomArrayLike is not iterable const arr2 = Array.from(myCustomArrayLike); console.log(arr2); // ['apple', 'banana']
- 展开运算符 (
映射功能:
- 展开运算符 (
...
):没有内置的映射功能。如果你需要转换并同时对元素进行操作,通常需要先用展开运算符转换,然后再链式调用map()
方法。 Array.from()
:第二个参数就是mapFn
,可以在转换过程中直接对元素进行映射处理,一步到位。
const nums = [1, 2, 3]; // 使用展开运算符 + map const doubledSpread = [...nums].map(n => n * 2); // [2, 4, 6] // 使用 Array.from + mapFn const doubledFrom = Array.from(nums, n => n * 2); // [2, 4, 6]
在这个例子中,虽然结果一样,但
Array.from
的写法在语义上更紧凑,尤其是在处理非数组的可迭代对象时,省去了中间步骤。- 展开运算符 (
何时选择谁?
选择展开运算符 (
...
):- 当你的源数据是一个可迭代对象,并且你只需要进行简单的转换(不需要在转换时进行映射)。
- 追求代码的简洁性和直观性。展开运算符的语法非常简洁明了。
- 例如:将
Set
转换为数组,或者将NodeList
转换为数组以使用forEach
等方法。
选择
Array.from()
:- 当你的源数据是类数组对象但不是可迭代对象(比如上面提到的自定义对象,或者某些旧的 DOM API 返回的类数组集合)。
- 当你需要在转换的同时对每个元素进行映射或转换。
mapFn
参数是其独有的优势。 - 当你需要生成一个特定长度的数组并填充值,例如
Array.from({ length: N }, (_, i) => i)
来生成一个数字序列。 - 需要更明确的语义,或者处理更复杂的转换逻辑时。
总的来说,对于简单的可迭代对象到数组的转换,展开运算符通常是首选,因为它更简洁。但如果你遇到非可迭代的类数组对象,或者需要在转换过程中进行复杂的数据处理,Array.from()
就会是更强大、更灵活的选择。它们是互补的工具,而不是替代品。
Array.from在实际开发中有哪些高级应用场景?
Array.from
不仅仅是用来转换 arguments
或 NodeList
那么简单,它的灵活性让它在很多实际开发场景中都能发挥出意想不到的妙用。
生成数字序列: 这是
Array.from
最常用也最强大的“非传统”用法之一。你不再需要手动循环来创建包含连续数字的数组。// 生成一个从 0 到 9 的数组 const tenNumbers = Array.from({ length: 10 }, (_, i) => i); console.log(tenNumbers); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // 生成一个从 1 到 5 的数组 const oneToFive = Array.from({ length: 5 }, (_, i) => i + 1); console.log(oneToFive); // [1, 2, 3, 4, 5] // 生成偶数序列 const evenNumbers = Array.from({ length: 5 }, (_, i) => i * 2); console.log(evenNumbers); // [0, 2, 4, 6, 8]
这在需要创建循环次数、分页页码、图表数据点等场景时,非常方便和简洁。
处理 DOM 集合,并进行复杂操作: 虽然展开运算符也能将
NodeList
转换为数组,但Array.from
结合mapFn
能让你在一步内完成更复杂的转换。// 假设页面上有多个带有 data-id 属性的 div /* <div data-id="item-1"></div> <div data-id="item-2"></div> */ // 获取所有 div 的 data-id 属性值,并存储在一个数组中 // const divIds = Array.from(document.querySelectorAll('div'), div => div.dataset.id); // console.log(divIds); // 例如:['item-1', 'item-2']
这比先转换成数组再
map
看起来更流畅,也更符合函数式编程的风格。克隆数组(浅拷贝): 虽然展开运算符
[...arr]
是更常见的数组浅拷贝方式,但Array.from(arr)
也能实现同样的效果。const originalArray = [1, { a: 1 }, 3]; const clonedArray = Array.from(originalArray); console.log(clonedArray); // [1, { a: 1 }, 3] console.log(clonedArray === originalArray); // false
在某些特定场景下,比如统一处理
arrayLike
和Array
时,使用Array.from
可能会带来代码风格上的一致性。从字符串创建字符数组(并进行处理): 字符串本身是可迭代的,所以
Array.from
可以将它拆分成字符数组。结合mapFn
,你甚至可以在拆分时就对字符进行转换。const word = "JavaScript"; const upperChars = Array.from(word, char => char.toUpperCase()); console.log(upperChars); // ['J', 'A', 'V', 'A', 'S', 'C', 'R', 'I', 'P', 'T']
这对于需要对字符串的每个字符进行独立操作的场景非常有用。
处理自定义的可迭代对象或类数组对象: 如果你自己定义了一个对象,并为其实现了
Symbol.iterator
接口,或者它只是一个简单的类数组结构,Array.from
都能轻松地将其转换为数组,方便你使用数组的所有方法。// 一个简单的自定义迭代器 const myIterable = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; } }; const arrFromIterable = Array.from(myIterable); console.log(arrFromIterable); // [1, 2, 3] // 一个自定义的类数组对象 const customData = { 0: 'Alice', 1: 'Bob', 2: 'Charlie', length: 3 }; const arrFromCustomData = Array.from(customData); console.log(arrFromCustomData); // ['Alice', 'Bob', 'Charlie']
这展示了
Array.from
在处理各种数据源时的强大通用性。
总的来说,Array.from
不仅仅是一个简单的转换工具,它更是一个多功能的数组构造器。通过巧妙地利用它的 mapFn
参数以及对各种数据类型的支持,我们可以在代码中实现更简洁、更富有表现力的逻辑。它鼓励我们用更现代、更函数式的方式来思考和处理数据集合。
以上就是《ES6Array.from转换类数组方法详解》的详细内容,更多关于的资料请关注golang学习网公众号!

- 上一篇
- 联想电源故障0x000000FE解决方法

- 下一篇
- unsafe.Pointer与普通指针有何不同?
-
- 文章 · 前端 | 49分钟前 | CSS JavaScript 数据 环形图 conic-gradient
- 用CSS环形图制作方法详解
- 159浏览 收藏
-
- 文章 · 前端 | 59分钟前 |
- JavaScript生成器函数使用详解
- 248浏览 收藏
-
- 文章 · 前端 | 59分钟前 |
- CSS定位属性详解:static、relative、absolute、fixed、sticky
- 367浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- async函数执行顺序全解析
- 262浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS嵌套技巧提升代码可读性
- 125浏览 收藏
-
- 文章 · 前端 | 1小时前 | CSS 数据拖拽 drag伪类 HTMLDragandDropAPI JavaScript事件
- CSS拖拽实现技巧全解析
- 427浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- HTML表格嵌入地图的几种方法
- 103浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- HTML表格斑马纹怎么加?CSS技巧分享
- 432浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- JS实现折叠面板的3种交互方式
- 391浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- 事件委托原理及使用方法详解
- 361浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- HTML瀑布流布局实现技巧详解
- 165浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- Node.js最新版本怎么选?稳定版推荐指南
- 125浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 边界AI平台
- 探索AI边界平台,领先的智能AI对话、写作与画图生成工具。高效便捷,满足多样化需求。立即体验!
- 418次使用
-
- 免费AI认证证书
- 科大讯飞AI大学堂推出免费大模型工程师认证,助力您掌握AI技能,提升职场竞争力。体系化学习,实战项目,权威认证,助您成为企业级大模型应用人才。
- 424次使用
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 561次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 662次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 570次使用
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览
-
- UI设计中为何选择绝对定位的智慧之道
- 2024-02-03 501浏览