当前位置:网站首页>请讲一讲JS中的 for...in 与 for...of (上)
请讲一讲JS中的 for...in 与 for...of (上)
2022-08-09 22:01:00 【lazytomato】
start
- 前几天睡觉老梦到去面试,面试官让我说说
for...in
和for...of
的区别。 - 一次两次也就罢了,关键是一直梦到,而且更关键的是我还说不明白。
- 现在学还来得及嘛?手动狗头
for…in
先看看MDN 的说明吧
解释:
for…in 语句以任意顺序迭代一个对象的除 Symbol 以外的可枚举属性,包括继承的可枚举属性。
思考:
任意顺序迭代
迭代的顺序是任意的,所以 MDN 后续文档又这么一句话备注:for...in不应该用于迭代一个关注索引顺序的 Array。
除 Symbol 以外的可枚举属性
所以需要注意下,for…in 无法遍历 Symbol 类型的属性;可枚举属性
是否可枚举,可以通过Object.defineProperty()
属性enumerable
定义(默认 enumerable 为 false);
快速判断属性是否可枚举可通过Object.prototype.propertyIsEnumerable()
包括继承的可枚举属性
原型链上的可枚举属性也会被遍历到。
验证一下:1.验证第一条 ”任意顺序迭代“
/* 我这里将属性值不为number类型的放在靠前的位置 */
var obj = {
4: 'string',
5: false,
6: function () {
console.log(1)
},
1: 1,
2: 2,
3: 3,
}
for (const key in obj) {
console.log(key, obj[key])
}
/* 1 1 2 2 3 3 4 string 5 false 6 [Function: 6] */
// for...in 遍历对象是按什么顺序遍历的? 有这么一个评论,仅供**参考**
// ES6 之前 Object 的键值对是无序的,所以遍历也无序可言。ES6 之后 Object 的键值对按照自然数、非自然数和 Symbol 进行排序,自然数是按照大小升序进行排序,其他两种都是按照插入的时间顺序进行排序。
2.验证第二条 “除 Symbol 以外的可枚举属性”
var obj = {
1: 11,
[Symbol('tomato')]: 'lazy', // 属性名直接写 Symbol表达式会报错,所以这里我用了中括号包裹一下。
name: '测试symbol',
}
for (const key in obj) {
console.log(key, obj[key])
}
/* 1 11 name 测试symbol */
3.验证第三条 “可枚举属性”
var obj = {
name: '测试可枚举属性',
}
for (const key in obj) {
console.log(key, obj[key])
}
/* name 测试可枚举属性 */
console.log(obj.propertyIsEnumerable('name')) // true
Object.defineProperty(obj, 'age', {
value: '18',
})
Object.defineProperty(obj, 'like', {
value: 'game',
enumerable: true,
})
console.log(obj.age) // 18
console.log(obj.like) // game
/* 验证enumerable默认为false */
console.log(obj.propertyIsEnumerable('age')) // false
console.log(obj.propertyIsEnumerable('like')) // true
for (const key in obj) {
console.log(key, obj[key])
}
/* name 测试可枚举属性 like game */
// 可以看到属性定义 enumerable: true 才会被 for...in遍历
4. 继承的可枚举属性
var obj = {
name: '测试是否会遍历原型上的属性',
}
var triangle = {
a: 1, b: 2, c: 3 }
function Person() {
this.color = 'red'
}
Person.prototype = triangle
var obj = new Person()
for (var key in obj) {
console.log(key, obj[key])
}
/* color red a 1 b 2 c 3 */
/* 正是因为 for...in 会遍历对象原型链上可枚举的属性,所以一般使用for...in的时候会结合hasOwnProperty方法,确保读取到的属性是当前对象上的 */
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key])
}
}
/* color red */
// ps 原型链上的可枚举属性都会被遍历
总结
写了几个 for…in 的验证案例,对 for…in 有一个初步的了解。
- 建议应用场景:
- 需要遍历对象上的属性的时候;
- ps 不太建议遍历数组
- 其次需要注意的点:
- 迭代是任意顺序的
- 属性需要可枚举
- 注意 Symbol
- 注意原型链上的可枚举属性
- 相关的方法
Object.defineProperty()
enumerable
Object.prototype.propertyIsEnumerable()
边栏推荐
猜你喜欢
随机推荐
【微服务~Nacos】Nacos之配置中心
面试官:Redis 大 key 要如何处理?
Xiaohei leetcode's refreshing rainy day trip, just finished eating Yufei Beef Noodles, Mala Tang and Beer: 112. Path Sum
【软考 系统架构设计师】案例分析④ 软件架构风格
Blender程序化建模简明教程【PCG】
面试官:MySQL 中 update 更新,数据与原数据相同时会执行吗?大部分人答不上来!
mysql 找不到或无法加载已注册的 .Net Framework Data Provider。
肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
Good future, want to be a second new Oriental
Interviewer: How to deal with Redis big key?
R语言将列表数据转化为向量数据(使用unlist函数将列表数据转化为向量数据)
c:forEach varStatus属性
【软考 系统架构设计师】案例分析⑤ 质量属性和架构评估
级联下拉菜单的实现「建议收藏」
TRUNCATE表之后空间未释放
leetcode brush questions diary Calculate the number of elements on the right that is less than the current element
CGLIB源码易懂解析
pip 离线到内网安装包
mysql 、pg 查询日期处理
Evolution of MLOps