前端Tips#2 - 将 arguments 转换成Array的最佳实践

简介: 前端Tips#2 - 将 arguments 转换成Array的最佳实践

视频讲解

文字讲解

1、先讲结论

有很多种方式将 arguments 转换成数组,那么哪一种方式是最优的?

为节约大伙儿的时间,这里先说一下结论:如果你想将 arguments 转换成数组,最好的方式是使用 rest 参数转换的方式(即使用 ... spread 操作符),比如:

function test(…args) {
   console.log(args)
}
test(1,2,3); // [1,2,3]

原因是:性能是 最优 的,可读性也挺好。

想知道为什么的话,可以继续往下看。

2、原因分析

arguments 对象是所有(非箭头)函数中都可用的局部变量,它是一个 “Array-Like” 对象,即 “像数组的对象”的意思,有些文章中也会翻译成 “伪数组对象”。(可以按索引取值、具有 length 属性,但不一定具备 pushconcat 等数组方法,具体可参考文章伪数组(ArrayLike)内容)

!> 注意:箭头函数中并不存在 arguments 对象

本期 tip 并不去详细讲 arguments 对象的知识内容(具体知识内容可阅读本讲末尾的参考文章),本讲着重讲解把它转换成数组时的最佳实践。

浏览了许多技术文章,将 arguments 对象转换成数组基本是 4 种方式:

  1. 使用 Array.prototype.slice.call(arguments)进行转换,或者是使用等效方法 [].slice.call(arguments);
  2. 使用 Array.from(arguments) 进行转换
  3. 使用 for 循环挨个将 arguments 对象中的内容复制给新数组中
  4. 利用 ES6 中的 rest 参数转换,let a = (...args) => args;

大多数文章也仅仅是讲到这里为止,并没有继续讨论以上哪种方式最优。

接下来我们就用基准测试(Benchmark)的方式来量化上述那种方式性能更好。

3、性能测试

在《做好准备:新的V8即将发布,Node 的性能正在改变》文中给了结论:

我将这文中提及的测试代码扔到 jsPerf 网站上(测试地址:https://jsperf.com/rest-arguments-slice ),运行结果如下:

图中数值越高代表性能越好,以上两幅图所反映的结果是一致的:

  1. 利用 ES6 中的 rest 参数转换性能最好
  2. 其次使用 for 循环方式转换
  3. [].slice 的方式性能较弱
  4. 最差的就是用 Array.from 进行转换

也可本地进行性能测试,测试代码在 这儿 获取;源码来自 官方提供的 benchmark 示例

因此,如果你想要将 arguments 转换成数组,那么毫无疑问应当使用 ES6 中的 rest 参数转换方式。

除了性能更好之外,rest 参数的用法相对于直接使用 arguments 还有如下优点:

  1. 箭头函数和普通函数都可以使用。
  2. 更加灵活,接收参数的数量完全自定义。
  3. 可读性更好,参数都是在函数括号中定义的,不会突然出现一个arguments,显得很突兀。

4、Q & A

在这里我简单解答一些常见的疑惑:

Q: 为什么需要将 arguments 对象转换成数组?

A: 答案也简单,因为 Array 实例提供了很多数组方法,比如 .push.concat 等,提供了更多数据操作方式,归根到底,转换成数组就是为了方便操作数据。

Q: 既然经常要将 arguments 转换成数组,为什么最初不把 arguments 设计成数组格式呢?

A: 按照文章 《JavaScript arguments 对象全面介绍》所言, arguments 在语言的早期就引入了,当时的 Array 对象具有 4 个方法: toStringjoinreversesortarguments 继承于 Object 的很大原因是不需要这四个方法。(当时设计的人也不知道后续的发展会对 arguments 有这方面的强需求...变化无处不在..)

Q: 为什么需要 Array-Like 对象(伪数组对象)的存在?

A: 前面说了,转换成数组也是为了提供更多数据操作方式;其实 Array-Like 对象的存在,也是为了给数据提供更多的操作的可能,因为可以在对象上挂载很多 自定义 的操作方法,使用起来灵活度会很高。

Q: 上述讨论的数组转换结果,是否也适应于其他 “伪数组对象”?

A: 因为 arguments 也是“伪数组对象”,不难推而广之,上面讨论的数组转换的方式都可以应用在“伪数组对象”上;至于每个转换方法的性能如何,我因为没有单独去测试过,所以也不能妄下定论,大家可以自己写 benchmark 去测试一下(个人猜测应该结论也差不多)。

5、参考文章

相关文章
|
2天前
|
存储 前端开发 JavaScript
前端基础(十一)_函数声明及调用、函数的形参与实参、arguments参数、函数的参数类型、函数中的问题
本文介绍了JavaScript中函数的声明及调用、形参与实参的概念、arguments对象的使用、函数参数的类型以及函数中this的作用。通过示例代码详细解释了函数如何接收参数、如何处理参数个数不匹配的情况,以及函数在不同上下文中this的指向。
7 1
|
1月前
|
缓存 前端开发 JavaScript
优化前端性能的十大最佳实践
在现代网页开发中,前端性能优化不仅仅是为了提升用户体验,还能显著提高网站的加载速度和响应时间。本文探讨了十大最佳实践,从优化资源加载到减少网络请求,再到提高页面渲染效率,每个实践都旨在解决常见的性能瓶颈。通过实现这些策略,开发者可以显著提升前端性能,提升用户满意度,并确保网站在各种设备上的流畅运行。
|
1月前
|
缓存 前端开发 JavaScript
高效开发现代 Web 应用:从前端到后端的最佳实践
在开发现代 Web 应用时,前端和后端技术的选择对项目的性能、可维护性和用户体验至关重要。本文将探讨如何通过现代工具和框架来优化前端和后端开发流程。我们将分析前端技术(如 React 和 Vue.js)与后端技术(如 Node.js 和 Django)的集成,并提供实际案例来展示如何实现高效开发。无论是对新手还是经验丰富的开发者,本指南都提供了宝贵的洞见和实用的技巧,以帮助提高开发效率并构建出色的 Web 应用。
|
1月前
|
缓存 前端开发 API
优化前端性能的最佳实践
在构建高效的前端应用时,性能优化是不可忽视的关键因素。本文将探讨一些实用的前端性能优化策略,包括资源的懒加载、合理的缓存策略、代码分割以及异步数据加载等方法。通过实施这些最佳实践,可以显著提升应用的响应速度和用户体验。
|
28天前
|
前端开发 JavaScript 大数据
React与Web Workers:开启前端多线程时代的钥匙——深入探索计算密集型任务的优化策略与最佳实践
【8月更文挑战第31天】随着Web应用复杂性的提升,单线程JavaScript已难以胜任高计算量任务。Web Workers通过多线程编程解决了这一问题,使耗时任务独立运行而不阻塞主线程。结合React的组件化与虚拟DOM优势,可将大数据处理等任务交由Web Workers完成,确保UI流畅。最佳实践包括定义清晰接口、加强错误处理及合理评估任务特性。这一结合不仅提升了用户体验,更为前端开发带来多线程时代的全新可能。
26 0
|
1月前
|
缓存 前端开发 JavaScript
优化前端性能的五种最佳实践
在现代 web 开发中,前端性能的优化是提高用户体验的关键。本文探讨了五种最佳实践来提升前端性能,包括代码分割、懒加载、压缩资源、优化渲染和使用缓存策略。这些方法不仅有助于减少加载时间,还能提高应用的响应速度和整体用户满意度。
|
2月前
|
前端开发 JavaScript 开发工具
前端开发最佳实践与工具推荐
【7月更文挑战第22天】前端开发是一个充满挑战和机遇的领域,掌握最佳实践和高效工具是提升开发效率、保证项目质量的关键。通过遵循版本控制、构建和部署、编写高质量代码、性能优化和安全性等最佳实践,并结合代码编辑工具、版本控制工具、包管理工具、构建工具、调试工具等实用工具,我们可以更好地完成前端开发任务,提升个人和团队的竞争力。
|
3月前
|
前端开发 JavaScript 测试技术
Jest与React Testing Library:前端测试的最佳实践
Jest和React Testing Library是React应用测试的核心工具。安装相关依赖后,在`jest.config.js`中配置Jest。测试时,编写描述性测试用例,使用`render`、`fireEvent`和`screen`来检查组件行为。Jest提供模拟功能,如模拟API调用。测试组件交互性时,模拟用户行为并验证状态变化。确保覆盖边缘情况,使用代码覆盖率报告评估测试完整性,并将测试集成到CI流程中。
63 1
|
4月前
|
前端开发 JavaScript
前端 js 经典:array 原生方法
前端 js 经典:array 原生方法
42 1
|
4月前
|
缓存 前端开发 JavaScript
如何优化前端性能:最佳实践与工具推荐
在当今互联网时代,用户对网页加载速度和性能的要求越来越高。本文将介绍一些优化前端性能的最佳实践,包括代码压缩、资源合并、懒加载等技术,并推荐一些实用的工具,帮助开发者提升网页加载速度和用户体验。