对于 JavaScript 中循环之间的技术差异概述
可枚举的属性
可枚举对象的一个定义特征是,当通过赋值操作符向对象分配属性时,我们将内部 enumerable
标志设置为true
,这是默认值。
当然,我们可以通过将其设置为false
来更改此行为。
要点:可枚举的属性都可以用
for...in
遍历出来。
举个例子看看:
// 会出现在 for ... in 循环中
const gbols = {};
gbols.platform = "LogRocket";
Object.getOwnPropertyDescriptor(gbols, "platform");
// {value: "LogRocket", writable: true, enumerable: true, configurable: true}
for (const item in gbols) {
console.log(item)
}
// platform
// 不会出现在 for ... in 循环中
// 将 enumerable 设置为 false
Object.defineProperty(gbols, 'role', {value: 'Admin', writable: true, enumerable: false})
for (const item in gbols) {
console.log(item)
}
// platform
可迭代的对象
如果一个对象定义了它的迭代行为,那么它就是可迭代的。在这种情况下,将在for …of
构造中循环的值将定义其迭代行为。可迭代的内置类型包括Arrays
、Strings
、Sets
和Maps
。object
是不可迭代的,因为它没有指定@iterator method
。
在Javascript中,所有可迭代都是可枚举的,但不是所有的可枚举都是可迭代的。
for …in
在数据中查找对象,而for ..of
查找重复序列。来个例子看看:
const authors = ['小智', '小王', '小明', '小红'];
// 与 for in 循环一起使用
fro (const author in authors) {
console.log(author)
}
// 打印: 0,1,2,3
for (const author of authors) {
console.log(author)
}
// 打印:小智 小王 小明 小红
使用此构造时,需要牢记的是,如果调用了 typeof
得到的类型是 object
,则可以使用for…in
循环。
我们来看一下对authors
变量的操作:
typeof authors
// 打印的是 “object”,因此我们可以使用`for ..in`
乍一看感觉有点奇怪,但必须注意,数组是一种特殊的对象,它以索引为键。for ...in
循环找到对象时,它将循环遍历每个键。
for …in
遍历 authors
数组的方式可以用下面显式化的方式来理解:
const authors = {
0: 'Jade',
1: 'Dafe',
2: 'Gbols',
3: 'Daniel'
}
重要说明:如果可以追溯到对象(或从对象原型链继承它),因为for …in
将以不特定的顺序遍历键。
同时,如果实现 for.. of
构造的迭代器,则它将在每次迭代中循环遍历该值。
ForEach 和 map 方法
尽管可以使用forEach
和map
方法来实现相同的目标,但是它们的行为和性能方面存在差异。
基础层面上,当函数被调用时,它们都接收一个回调函数作为参数。
考虑下面的代码片段:
const scoresEach = [2,4 ,8, 16, 32];
const scoresMap = [2,4 ,8, 16, 32];
const square = (num) => num * num;
我们逐一列出其操作上的一些差异。
forEach
返回undefined
,而map
返回一个新数组:
let newScores = []
const resultWithEach = scoresEach.forEach((score) => {
const newScore = square(score);
newScores.push(newScore);
});
const resultWithMap = scoresMap.map(square);
console.log(resultWithEach) // undefined
console.log(resultWithMap) // [4, 16, 64, 256, 1024]
map
是一个纯函数,而forEach
则执行一些更改:
console.log(newScores) // [4, 16, 64, 256, 1024]
在我看来,map
倾向于函数式编程范例。与forEach
不同的是,我们并不总是需要执行一次更改来获得想要的结果,在forEach
中,我们需要对newscore
变量进行更改。在每次运行时,当提供相同的输入时,map
函数将产生相同的结果。同时,forEach
对应项将从最后一次更改的前一个值中获取数据。
链式
map
可以使用链式操作,因为map
返回的结果是一个数组。因此,可以立即对结果调用任何其他数组方法。换句话说,我们可以调用filter
, reduce
, some
等等。对于forEach,这是不可能的,因为返回的值是undefined
。
性能
map
方法的性能往往优于forEach
方法。
检查用map
和forEach
实现的等效代码块的性能。平均而言,map
函数的执行速度至少要快50%
。
注意:此基准测试取决于你使用的计算机以及浏览器的实现。
总结
在上面讨论的所有循环结构中,为我们提供最多控制的是for..of
的循环。我们可以将它与关键字return
、continue
和break
一起使用。这意味着我们可以指定我们希望对数组中的每个元素发生什么,以及我们是想早点离开还是跳过。
原文:https://medium.com/better-pro...
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java 记一次自定义比较器中compareTo方法使用long强转int作为比较结果产生的bug
- SpringCloud 使用feign报错
- Java 使用Runtime在一个Java程序中启动和关闭另一个Java程序
- 解决虚拟机Centos7 报错 curl#56
- Java 桶排序实现 如何判断该放到哪个桶里
- Java selenium使用ChromeDriver截图 解决get超时后续任务报错问题
- 冒泡排序-排序算法
- Java中JDBC工具类封装
- 3.深入k8s:Deployment控制器
- 使用FreeSurfer进行脑区分割
- android 调试 adb
- Java实现基本数据结构(三)——队列
- Java实现基本数据结构(二)——栈
- Java实现基本数据结构(一)——数组
- concurrently 实现前后端连载启动