(for in)遍历键名和 (for of)遍历键值,这种说法严谨吗?

for in与for of遍历详解
本文探讨了`for in`和`for of`在遍历数组和对象时的行为。`for in`主要用于遍历对象的可枚举属性,包括数组的索引,而`for of`遍历的是实现了迭代器接口的数据结构。对于数组,`for of`遍历的是元素值,而对于未定义迭代器的对象,会报错。总结指出,称`for in`遍历键名和`for of`遍历键值并不严谨,需结合具体数据结构和遍历方式理解。


[1] const arr = [7, 8, 9];
const obj = {
  a: 4,
  b: 5,
  c: 6
};
[2] for (let v in arr){
 console.log(v);
}
// 0, 1, 2
[3 ]for (let v in obj){
 console.log(v);
}
// a, b, c
[4] arr.child = 'child';
[5] arr.__proto__.getChild = function () {
    return this.child;
     };
[6] Array.prototype.parent = 'parent';
[7] for (let v in arr){
        console.log(v);
     }
//  0, 1, 2, child, getChild, parent
[8]for (let v of arr){
       console.log(v);
    }
// 7, 8, 9
[9] for (let v of arr.values()){
       console.log(v);
    }
// 7, 8, 9
[10] for (let v of obj){
       console.log(v);
    }
// 报错 
[11] typeof arr.keys(); // 'object'
arr.keys() instanceof Array; // false
arr.keys() instanceof Object; // true

for in

for in在ES5中便出现了。一般用来遍历对象属性。但也可用于数组遍历,返回的值是数组的索引,因为,严格来说,数组也是一个对象,所对应的属性是每个值的索引。 **for-in只遍历对象自身的和继承的可枚举的属性(摘自 阮一峰ECMAScript 6 入门-对象扩展一章)**。
如[4]、[5]、[6]所示,为数组添加可遍历属性 **(所对应描述器descriptor的enumerable属性为true)** ,在[7]中用for-in遍历都可遍历出来。

for of

for of为ES6新增遍历方法。其可遍历所有具有 iterator 接口的数据结构。for...of循环内部调用的是数据结构的Symbol.iterator方法(generator函数)。**(摘自 阮一峰ECMAScript 6 入门--Iterator 和 for...of 循环一章)**。Symbol.iterator方法返回的是一个遍历器,当用for-of去遍历的时候, 自动调用里面的next方法。
如[8], [9]所示,数组原生具备iterator接口(即默认部署了Symbol.iterator属性),for...of循环本质上就是调用这个接口产生的 **遍历器**。再看?例子 **(摘自 阮一峰ECMAScript 6 入门--Iterator 和 for...of 循环一章)**,对象obj默认调用的遍历器生成器是obj.values即obj[Symbol.iterator] 。
```
const colorArr = ['red', 'green', 'blue'];
for(let v of colorArr) {
  console.log(v); 
}
// red green blue
const colorObj = {};
colorObj[Symbol.iterator] = colorArr[Symbol.iterator].bind(colorArr);

for(let v of colorObj) {
  console.log(v); 
}
// red green blue
```
总结

所以说,(for in)遍历键名和 (for of)遍历键值,这种说法并不严谨。for in确实是遍历属性,而且更是遍历对象自身的和继承的可枚举的属性。但是,for of遍历键值这种说法便不严谨了,比如说我们一开始在[1]中声明的对象obj,键名为a,b, c;  键值为4,5,6;


按照(for of)遍历键值这种说法,用for of遍历obj应该返回键值4,5,6。可是如[10]所示,程序执行报错了。因为对象默认是没有iterator接口的,我们不可以直接遍历,当我们需要遍历对象的属性时,可以调用Object.keys()返回一个数组,用来遍历所有的键名。当我们需要遍历对象的属性值时,应该调用obj.values()返回一个数组,用来遍历所有的键值。并不是说for-of遍历键值,for-of具体遍历并返回的是什么,是视of后面返回的数组对应是什么。就obj这个对象来说,我们可以遍历obj的键值(Object.values(obj)),也可以遍历obj的键名(Object.keys(obj)),更可以遍历对象的obj的键值对(Object.entires(obj))。                                                                                          
同样。for-of遍历数组,数组是默认具有iterator接口的,即arr.values(),具体遍历并返回的是什么,是视of后面返回的遍历器对象是什么。arr的键值(arr.values()),也可以遍历数组arr的键名(arr.keys()),更可以遍历数组的arr的键值对(arr.entires())。


遍历器对象是一个对象,不是数组。如[11]所示,arr.keys() 是对象Object的实例,并不是数组实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值