博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你可能并没有真正理解for-in
阅读量:6997 次
发布时间:2019-06-27

本文共 2242 字,大约阅读时间需要 7 分钟。

for in

要很好的掌握for-in的使用你可能只需要记住下面一句话:

特定顺序遍历一个对象及其原型链的所有可枚举属性(但是不包括 Symbol)

我们先上代码,再一一解释。

const sym = Symbol("key");// 创建一个对象const obj = {    key: 23,    name: "singcl",    action: Symbol("action"),    [sym]: "symbol",    3: "the number is 3",    1: "the number is 1"};// 使用 Object.defineProperty() 给obj添加一个不可枚举属性Object.defineProperty(obj, "water", {    enumerable: false,    value: "这是一个不可枚举属性"});// 使用 Object.defineProperty() 给obj添加一个可枚举属性Object.defineProperty(obj, "people", {    enumerable: true,    value: "这是一个可枚举属性"});// 设置对象原型Object.setPrototypeOf(obj, { protoKey: "这是一个定义在原型上的属性" });// for-in 遍历对象const res = [];for (const key in obj) {    res.push(key);}// 输出遍历结果console.log(res); // [ '1', '3', 'key', 'name', 'action', 'people', 'protoKey' ]console.log(obj.protoKey); // 这是一个定义在原型上的属性console.log(obj.water); // 这是一个不可枚举属性console.log(obj.people); // 这是一个可枚举属性console.log(obj.propertyIsEnumerable("water")); // falseconsole.log(obj.propertyIsEnumerable("people")); // trueconsole.log(obj.propertyIsEnumerable(sym)); // true复制代码

现在我们就来一样解释:

1.特定顺序

我们在obj上添加的属性的顺序和我们最终for-in循环输出的结果的顺序并不一致,那么for-in遍历到底是按什么顺序遍历的呢?

其实是按以下顺序遍历的:

  1. 首先遍历所有数值键,按照数值升序排列。
  2. 其次遍历所有字符串键,按照加入时间升序排列。
  3. 最后遍历所有 Symbol 键,按照加入时间升序排列

对照上面的代码看看是不是呢。

2.对象及其原型链

for-in循环遍历对象时候会遍历对象以及对象原型链上的属性。上面protoKey是定义在对象的原型上而不是对象本身上。但是依然被for-in遍历到了。

3.可枚举属性

  • water是我们使用Object.defineProperty()定义在 obj 上的一个不可枚举属性
  • people是我们使用Object.defineProperty()定义在 obj 上的一个可枚举属性

观察for-in循环的输出结果我们看的people被遍历到了,而water却没有被遍历到。我们再次来确认下:

// 查看obj 上是否有water和people属性console.log(obj.water); // 这是一个不可枚举属性console.log(obj.people); // 这是一个可枚举属性// 确定water 和 people 是否可枚举console.log(obj.propertyIsEnumerable("water")); // falseconsole.log(obj.propertyIsEnumerable("people")); // true复制代码

的确 people 是 obj 上可枚举属性,被遍历到了,而water是 obj 上不可枚举属性,没有被遍历到。

obj 上key, name, action等通过字面量方式添加的属性默认是可枚举的。

4.但是不包括 Symbol

你可能有疑问: obj 上 Symbol类型的属性sym 也没有被遍历到,是不是因为它是不可枚举属性? 那么我们验证下:

console.log(obj.propertyIsEnumerable(sym)); // true复制代码

咦?obj 上 Symbol类型的属性sym是可枚举的,但是却没有被遍历到。

这就是为什么要单独指出:可枚举属性(但是不包含 Symbol) 要想获得Symbol类型的属性,我们可以使用Object.getOwnPropertySymbols()。这里就不讲了,如果有兴趣可以自己去了解。

总结

特定顺序遍历一个对象及其原型链的所有可枚举属性(但是不包括 Symbol)

for-in循环的4个要点:

  1. 特定顺序
  2. 对象及其原型链
  3. 可枚举属性
  4. 不包含 Symbol 类型

参考:

转载于:https://juejin.im/post/5b9d172f5188255c4a711023

你可能感兴趣的文章
jvm调优经验分享
查看>>
高速公路坐标高程计算软件3.3版本发布
查看>>
CF519 ABCD D. A and B and Interesting Substrings(map,好题)
查看>>
【转】Android开发之旅:环境搭建及HelloWorld
查看>>
qt creator 快捷键 (二)
查看>>
【分享】博客美化(3)为博客添加一个漂亮的分享按钮
查看>>
VS2010发布、打包安装程序
查看>>
hibernate事务配置Aop aop:advisor模式
查看>>
XSS攻击及防御
查看>>
oracle插入
查看>>
在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)...
查看>>
android开发,assets下面的资源文件不会变化/改动
查看>>
使用D3D渲染YUV视频数据
查看>>
sqlite 一条记录判断一个字段是否like另一个字段
查看>>
IE6图片元素img下出现多余空白问题
查看>>
模式与框架
查看>>
Kinect开发学习笔记之(一)Kinect介绍和应用
查看>>
nginx编译配置
查看>>
[LeetCode] 3Sum Closest 最近三数之和
查看>>
如何解决严重拖延症
查看>>