for...in 和 for...of有什么区别
for…in 和 for…of有什么区别
for…in
1.遍历数组
const arr = ["element1", "element2", "element3"] |
2.遍历对象
const obj = { |
检测是否可枚举
console.log("🚀 ~ ", Object.getOwnPropertyDescriptor(obj, "name"))
// 输出:
// { value: 'obj', writable: true, enumerable: true, configurable: true }
// enumerable: true 可枚举
3.遍历字符串
const str = "hello!world" |
4.遍历字符串,包含unicode字符
const str2 = "a𠮷c" |
5.遍历对象,父类属性也会遍历出来
const fatter = { |
for…of
示例:
let str = 'a𠮷c'; |
遍历Map
const map = new Map([["a", 1], ["b", 2], ["c", 3]]); |
Set和Array
entries()、keys()、values()都返回一个迭代器对象entries()返回值为集合的键值对[[key, value], [key, value], [key, value]](对于数组,key 就是索引值;对于 Set,key 就是 value)keys()返回值为集合的键名[key, key, key](对于数组,key 就是索引值;对于 Set,key 就是 value)values()返回值为集合的值[value, value, value]
const arr2 = ["a", "b", "c"]; |
for…in 和 for…of 的区别
| for…in | for…of | |
|---|---|---|
| key | value | 结果 |
| 可枚举属性 | 可迭代对象 | 遍历 |
| 遍历对象 | 遍历数组 | 常用 |
拓展操作
const father = { |
1.Object.Keys 获取键名数组
for (const key of Object.keys(instance)) { |
Object.keys不会遍历原型链上的属性、以及自身不可枚举的属性
Object.keys返回的是一个数组,所以可以使用数组的方法
ps:
Object.keys与for in的区别for (const instanceKey in instance) {
console.log(instanceKey, "for in")
}
// 输出:
// a b c fatherAttrfor in会遍历原型链上的属性,但是同样不会遍历自身不可枚举的属性
2.Object.getOwnPropertyNames() 获取键名数组
Object.getOwnPropertyNames() 与 Object.keys() 的区别在于,Object.getOwnPropertyNames() 会遍历自身不可枚举的属性
for (const instanceKey of Object.getOwnPropertyNames(instance)) { |
3.Object.entries() 获取键值对数组
Object.entries()不会遍历原型链上的属性和自身不可枚举的属性
for (const instanceKey of Object.entries(instance)) { |
ps: 当使用对象初始化一个Map实例,可以使用
Object.entries()来初始化const obj = {a: 1, b: 2, c: 3};
const map = new Map(Object.entries(obj));
console.log(map.get("a")) // 1
4.Object.values() 获取对象的属性值数组
Object.values()不会遍历原型链上的属性和自身不可枚举的属性
for (const instanceKey of Object.values(instance)) { |
5.Object.getOwnPropertySymbols()获取Symbol属性名
上面的方法都无法获取Symbol属性名,只能通过
Object.getOwnPropertySymbols()来获取
instance[Symbol("e")] = 5; |
什么是可枚举数据呢?
举个例子来说
const obj = { x: 100 } |
我们使用 Object.getOwnPropertyDescriptors 方法获取指定对象所有的自有属性的属性描述符。

这时候发现他的每一个属性中 enumerable 都是 true,这时候他就是可枚举的。
如果一个属性的enumerable为false,下面三个操作不会取到该属性。
for..in循环
Object.keys方法
JSON.stringify方法
所以一般情况下 对象、数组、字符串都是可枚举的
什么是可迭代数据呢?
for…of用于可迭代的数据,如:
- 数组
- 字符串
- Map
- Set
const arr = [1, 2, 3] |
数组中有个 Symbol.iterator的属性:
- 1.只要一个数据已经实现了Iterator接口, 那么这个数据就有一个叫做
[Symbol.iterator]的属性 - 2.
[Symbol.iterator]的属性会返回一个函数 - 3.
[Symbol.iterator]返回的函数执行之后会返回一个对象 - 4.
[Symbol.iterator]函数返回的对象中又一个名称叫做next的方法 - 5.next方法每次执行都会返回一个对象
{value: 1, done: false} - 6.这个对象中存储了当前取出的数据和是否取完了的标记

就类似设计模式中的迭代器模式:
不断有next、next去调用:
- A next() => B
- B next() => C
- 如此 如此
了解了上面的情况之后,我们也可以理解什么时候用 for…of 什么时候用 for…in?
- for…in可以用在可枚举的数据
- for…of用于可迭代的数据
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 EvanSky!






