Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >给初学者:JavaScript 中数组操作注意点

给初学者:JavaScript 中数组操作注意点

作者头像
企鹅号小编
发布于 2018-01-23 12:03:19
发布于 2018-01-23 12:03:19
8770
举报
文章被收录于专栏:编程编程

作者:CarterLi

https://segmentfault.com/a/1190000012463583

不要用 for_in 遍历数组

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

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

1.遍历顺序不固定

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

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

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

3.运行效率低下

尽管理论上 JavaScript 使用对象的形式储存数组,JavaScript 引擎还是会对数组这一非常常用的内置对象特别优化。

https://jsperf.com/for-in-vs-for-of-vs-foreach:可以看到使用 for_in 遍历数组要比使用下标遍历数组慢 50 倍以上。

PS:你可能是想找for_of

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

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

1.会使某些特定值转换为

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

2.会丢失值为 undefined 的键值对

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

3.会将 Date 对象转换为字符串

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

4.运行效率低下

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

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

https://jsperf.com/deep-clone-array-using-native-json-and-custom-deepclone

不要用 arr.find 代替 arr.some

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

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

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

不要用 arr.map 代替 arr.forEach

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

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

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

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

补:forEach 与 break

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

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

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

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

我们可以仿照这样的做法,来实现的:

还有其他方法,比如用代替。

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

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

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

和的性能测试:https://jsperf.com/array-foreach-vs-for-of-entries/1 Chrome中要快一些哦

本文来自企鹅号 - 前端大全媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文来自企鹅号 - 前端大全媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面了十多家,总结出20道JavaScript 必考的面试题!
面临毕业季,相信有很多朋友正在进行找工作,背面试题;今天就分享给大家20道JavaScript必会的问题
程序员老鱼
2023/09/07
2370
面了十多家,总结出20道JavaScript 必考的面试题!
深拷贝真的难
深拷贝浅拷贝的原理我是已经懂了,之前也有分享过。只是深拷贝浅拷贝的方法却从来没有真的去了解过。
wade
2021/02/23
4160
深拷贝真的难
一篇文章彻底搞懂浅拷贝和深拷贝的区别_深拷贝和浅拷贝的题
由博主《前端初级工程师面试系列一JS基础》文章一JS变量类型引伸的考点,变量类型分为基本类型和引用类型,那么在变量拷贝赋值时,也是不一样的,分为浅拷贝和深拷贝,是面试中常考的知识点,也是实际开发中经常会用到的内容。
全栈程序员站长
2022/11/10
5310
一篇文章彻底搞懂浅拷贝和深拷贝的区别_深拷贝和浅拷贝的题
06_JavaScript数组
保存一个班级学生信息,每个数组元素都代表一个学生,而每个学生都使用一个一维数组分别表示其姓名、学号、年龄等信息,这样通过一个变量即可有规律的保存一个班级的所有学生信息,方便开发时进行处理。
张哥编程
2024/12/13
1640
还搞不清JS里for..in for...of forEach map各种遍历方式的区别吗
for循环是JS里最简单也是最通用的遍历方式,我们需要知道遍历的次数。 for循环里return,break等关键字都是可以用的
henu_Newxc03
2022/04/13
1.5K0
JavaScript 常见面试题速查
instanceof 可以正确判断对象的类型,其内部运行机制是判断其原型链中能否找到该类型的原型。
Cellinlab
2023/05/17
5740
JavaScript 常见面试题速查
最全的数组操作方法,你造吗?
在 JavaScript 中,对于数组的操作非常频繁,对应的 API 也很丰富 。ECMAScript 规范在每一版发布时,都会提供新的 API 来增强数组的操作能力,下面将详细介绍这些 API 的一些特性。
grain先森
2019/03/29
7730
最全的数组操作方法,你造吗?
JS的数据类型/判断方法/栈与堆/深浅拷贝
用来检测:undefined、string、number、boolean、symbol、object、function 无法检测引用类型里的Array
杨肆月
2019/08/20
1.5K0
JS的数据类型/判断方法/栈与堆/深浅拷贝
前端面试拔高题
对象是 JS 中基本类型之一,而且和原型链、数组等知识息息相关。不管是面试中,还是实际开发中我们都会碰见深拷贝对象的问题。
李才哥
2019/09/04
9230
前端面试拔高题
大全!JavaScript中深浅拷贝内部方法与手写函数
怎么理解这句话:浅拷贝过程实质上是创建了一个新的变量,但这个新变量与原变量指向同一个内存地址上的对象。这意味着原对象和拷贝对象共享相同的数据结构和内部状态。因此,对拷贝对象所做的任何修改,如果涉及到修改共享的数据结构,也会影响到原始对象。同样的,原始对象所做的任何修改,如果涉及到修改共享的数据结构,也会影响到拷贝对象。
用户6256742
2024/08/13
2010
JavaScript语句之常用for循环
普通for循环在 Array 中可以使用。遍历数组时,是遍历数组下标索引,通过下标去取值。
青年码农
2021/03/23
4100
JavaScript 进阶
引用计数 IE采用的引用计数算法, 定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用。 算法:
小城故事
2023/04/03
1.3K0
JavaScript 进阶
JavaScript 引用类型
关联数组:数组下标可以自定义,{}。length属性:无。for key in arr遍历。
城市中的游牧民族
2019/02/21
9320
JavaScript 引用类型
js中的四种for循环
最近刷题时遇到了几种不同for循环,因为没有深入了解导致做题时无法区分它们的用法,尤其是在以及在使用时的注意点。
用户7741497
2022/03/06
2K0
前端面试被问到的js手写面试题汇总
类的继承在几年前是重点内容,有n种继承方式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深入理解的去看红宝书即可,我们目前只实现一种最理想的继承方式。
helloworld1024
2022/11/18
5890
一文搞懂JS中的赋值·浅拷贝·深拷贝
为什么写拷贝这篇文章?同事有一天提到了拷贝,他说赋值就是一种浅拷贝方式,另一个同事说赋值和浅拷贝并不相同。我也有些疑惑,于是我去MDN搜一下拷贝相关内容,发现并没有关于拷贝的实质概念,没有办法只能通过实践了,同时去看一些前辈们的文章总结了这篇关于拷贝的内容,本文也属于公众号【程序员成长指北】学习路线中【JS必知必会】内容。
coder_koala
2019/07/30
3.2K0
一文搞懂JS中的赋值·浅拷贝·深拷贝
前端知识点总结js篇(中)
(总结不够全面,建议参考es6.ruanyifeng.com/#docs/promi…
zhouzhouya
2023/10/26
2700
前端知识点总结js篇(中)
2021JavaScript面试题(最新)不定时更新(2021.11.6更新)
js 一共有六种基本数据类型,分别是 Undefined、Null、Boolean、Number、String,还有在 ES6 中新增的 Symbol 类型。 Symbol 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
全栈程序员站长
2022/09/07
2.6K0
2022高频前端面试题合集之JavaScript篇(上)
解析:该题主要考察就是对 js 中的继承是否了解,以及常见的继承的形式有哪些。最常用的继承就是「组合继承」(伪经典继承)和圣杯模式继承。下面附上 js 中这两种继承模式的详细解析。
程序员法医
2022/12/20
1.2K0
2022高频前端面试题合集之JavaScript篇(上)
JavaScript 10分钟入门
简介 JavaScript是一门面向对象的动态语言,他一般用来处理以下任务: 1、修饰网页 生成HTML和CSS 生成动态HTML内容 生成一些特效 2、提供用户交互接口 生成用户交互组件 验证用户输入 自动填充表单 3、能够读取本地或者远程数据的前端应用程序,例如http://web-engineering.info/JsFrontendApp-Book 4、通过Nodejs实现像JAVA,C#,C++一样的服务端程序 5、实现分布式WEB程序,包括前端和服务端 当前浏览器所支持的JavaScript的
前朝楚水
2018/04/04
1.3K0
JavaScript 10分钟入门
相关推荐
面了十多家,总结出20道JavaScript 必考的面试题!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档