搜索
首页web前端js教程有关JavaScript数组操作难点(详细教程)

有关JavaScript数组操作难点(详细教程)

Jun 20, 2018 pm 01:56 PM
javascript数组

本篇文章通过例举代码分析的方式给大家讲解了JavaScript数组操作难点以及需要注意的地方,一起学习参考下吧。

以下内容是学习JavaScript数组的时候总结的经验以及需要注意的点。

不要用 for_in 遍历数组

这是 JavaScript 初学者常见的误区。for_in 用于遍历对象中包括原型链上的所有可枚举的(enumerable)的 key,本来不是为遍历数组而存在。

使用 for_in 遍历数组有三点问题:

1、遍历顺序不固定

JavaScript 引擎不保证对象的遍历顺序。当把数组作为普通对象遍历时同样不保证遍历出的索引顺序。

2、会遍历出对象原型链上的值。

如果你改变了数组的原型对象(比如 polyfill)而没有将其设为 enumerable: false,for_in 会把这些东西遍历出来。

3、运行效率低下。

尽管理论上 JavaScript 使用对象的形式储存数组,JavaScript 引擎还是会对数组这一非常常用的内置对象特别优化。 https://jsperf.com/for-in-vs-...
可以看到使用 for_in 遍历数组要比使用下标遍历数组慢 50 倍以上

PS:你可能是想找 for_of

不要用 JSON.parse(JSON.stringify()) 深拷贝数组

有人使用 JSON 中深拷贝对象或数组。这虽然在多数情况是个简单方便的手段,但也可能引发未知 bug,因为:会使某些特定值转换为 null

NaN, undefined, Infinity 对于 JSON 中不支持的这些值,会在序列化 JSON 时被转换为 null,反序列化回来后自然也就是 null

会丢失值为 undefined 的键值对

JSON 序列化时会忽略值为 undefined 的 key,反序列化回来后自然也就丢失了

会将 Date 对象转换为字符串

JSON 不支持对象类型,对于 JS 中 Date 对象的处理方式为转换为 ISO8601 格式的字符串。然而反序列化并不会把时间格式的字符串转化为 Date 对象

运行效率低下。

作为原生函数,JSON.stringifyJSON.parse 自身操作 JSON 字符串的速度是很快的。然而为了深拷贝数组把对象序列化成 JSON 再反序列化回来完全没有必要。

我花了一些时间写了一个简单的深拷贝数组或对象的函数,测试发现运行速度差不多是使用 JSON 中转的 6 倍左右,顺便还支持了 TypedArray、RegExp 的对象的复制

https://jsperf.com/deep-clone...

不要用 arr.find 代替 arr.some

Array.prototype.find 是 ES2015 中新增的数组查找函数,与 Array.prototype.some 有相似之处,但不能替代后者。

Array.prototype.find 返回第一个符合条件的值,直接拿这个值做 if 判断是否存在,如果这个符合条件的值恰好是 0 怎么办?

arr.find 是找到数组中的值后对其进一步处理,一般用于对象数组的情况;arr.some 才是检查存在性;两者不可混用。

不要用 arr.map 代替 arr.forEach

也是一个 JavaScript 初学者常常犯的错误,他们往往并没有分清 Array.prototype.mapArray.prototype.forEach 的实际含义。

map 中文叫做 映射,它通过将某个序列依次执行某个函数导出另一个新的序列。这个函数通常是不含副作用的,更不会修改原始的数组(所谓纯函数)。

forEach 就没有那么多说法,它就是简单的把数组中所有项都用某个函数处理一遍。由于 forEach 没有返回值(返回 undefined),所以它的回调函数通常是包含副作用的,否则这个 forEach 写了毫无意义。

确实 mapforEach 更加强大,但是 map 会创建一个新的数组,占用内存。如果你不用 map 的返回值,那你就应当使用 forEach

补:心得补充

ES6 以前,遍历数组主要就是两种方法:手写循环用下标迭代,使用 Array.prototype.forEach。前者万能,效率最高,可就是写起来比较繁琐——它不能直接获取到数组中的值。

笔者个人是喜欢后者的:可以直接获取到迭代的下标和值,而且函数式风格(注意 FP 注重的是不可变数据结构,forEach 天生为副作用存在,所以只有 FP 的形而没有神)写起来爽快无比。但是!不知各位同学注意过没有:forEach 一旦开始就停不下来了。。。

forEach 接受一个回调函数,你可以提前 return,相当于手写循环中的 continue。但是你不能 break——因为回调函数中没有循环让你去 break

[1, 2, 3, 4, 5].forEach(x => {
 console.log(x);
 if (x === 3) {
  break; // SyntaxError: Illegal break statement
 }
});

解决方案还是有的。其他函数式编程语言例如 scala 就遇到了类似问题,它提供了一个函数
break,作用是抛出一个异常。

我们可以仿照这样的做法,来实现 arr.forEachbreak

try {
 [1, 2, 3, 4, 5].forEach(x => {
  console.log(x);
  if (x === 3) {
   throw 'break';
  }
 });
} catch (e) {
 if (e !== 'break') throw e; // 不要勿吞异常。。。
}

还有其他方法,比如用 Array.prototype.some 代替 Array.prototype.forEach

考虑 Array.prototype.some 的特性,当 some 找到一个符合条件的值(回调函数返回 true)时会立即终止循环,利用这样的特性可以模拟 break

[1, 2, 3, 4, 5].some(x => {
 console.log(x);
 if (x === 3) {
  return true; // break
 }
 // return undefined; 相当于 false
});

some 的返回值被忽略掉了,它已经脱离了判断数组中是否有元素符合给出的条件这一原始的含义。

在 ES6 前,笔者主要使用该法(其实因为 Babel 代码膨胀的缘故,现在也偶尔使用),ES6 不一样了,我们有了 for...of。for...of 是真正的循环,可以 break

for (const x of [1, 2, 3, 4, 5]) {
 console.log(x);
 if (x === 3) {
  break;
 }
}

但是有个问题,for...of 似乎拿不到循环的下标。其实 JavaScript 语言制定者想到了这个问题,可以如下解决:

for (const [index, value] of [1, 2, 3, 4, 5].entries()) {
 console.log(`arr[${index}] = ${value}`);
}

Array.prototype.entries

for...offorEach 的性能测试:https://jsperf.com/array-fore... Chrome 中 for...of 要快一些哦

以上是有关JavaScript数组操作难点(详细教程)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:选择合适的工具Python vs. JavaScript:选择合适的工具May 08, 2025 am 12:10 AM

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript:了解每个的优势Python和JavaScript:了解每个的优势May 06, 2025 am 12:15 AM

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

JavaScript的核心:它是在C还是C上构建的?JavaScript的核心:它是在C还是C上构建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript应用程序:从前端到后端JavaScript应用程序:从前端到后端May 04, 2025 am 12:12 AM

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境