for..in 和 for..of区别

首先for…in和for…of都是用来迭代一些东西,但是他们在迭代数据的时候有很大的不同

for…in

for…in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。

// 数组
var arr = [10, 20, 30, 40, 50];
Array.prototype.myArray = function(){};
arr.youArray = 'youSome';

// 对象
var obj = {a: 10, b: 20, c: 30, d: 40};
Object.prototype.myObject = function(){}
obj.youObject = 'youObject';
    
for(let i in arr){
  console.log(i);
}
// 上边代码输出结果:
// 0 1 2 3 4 youArray myArray myObject

可以看到for…in 遍历数组的缺点

  1. 把Array.prototype.myArray 数组对象原型上的方法和youArray都做了遍历输出;
  2. 因为数组也属于对象,也是由Object缔造出来的,所以也会把Object原型上的方法遍历出来。
    在这种情况下我们如果使用for…in进行遍历就需要做一些判断
// 数组
var arr = [10, 20, 30, 40, 50];
Array.prototype.myArray = function(){};
arr.youArray = 'youSome';

for(let i in arr){
    if(arr.hasOwnProperty(i)){
        console.log(i);
    }
}
// 上边的代码输出结果:
// 0 1 2 3 4 youArray

上边的代码中我们使用了hasOwnProperty方法进行当前项是否为自身属性而不是原型或者继承的属性。
通过上边代码示例可以看出for…in并不适合用来遍历数组,在遍历数组的时候最好的方法是使用数组自身提供的遍历方法如:forEach\map\filter\for…of等方法进行遍历。

for…of

for...of语句主要用在原型上部署了Iterator迭代接口的数据类型上(包括 ArrayMapSetStringTypedArrayarguments 对象等等)可以循环遍历数据类型中的每一项调用自定义迭代钩子,并为每个不同属性的值执行语句

// 数组
var arr = [10, 20, 30, 40, 50];
Array.prototype.myArray = function(){};
arr.youArray = 'youSome';

for(let v of arr){
  console.log(v);
}
//上边输出的结果是
// 10 20 30 40 50

可以看出for…of遍历的主要是值,同时它不会遍历出原型上的属性方法,和静态属性方法。

for…of循环不能用在对象上,因为对象没有部署Symbol.iterator迭代器所以没办法使用for…of进行遍历,我们可以给我们的对象增加迭代器来实现。
迭代器规则是:

  1. 迭代器需要时一个方法,并且返回一个对象;
  2. 对象中需要有next方法,表示每次进行迭代对象中的项目都调用该方法;
  3. 该方法也需要返回一个对象并且对象中有value、done项
// 定义一个对象
var myObject = {
    a: 10,
    b: 20,
    c: 30,
    d: 40,
    list:[
        10, 20, 30, 40
    ]
};
// 给对象增加迭代器,供for...of使用
myObject[Symbol.iterator]  = function(){
    // 定义一个变量用来存储迭代器的循环次数
    let index = 0;
    // 把当前的this存储下来
    let that = this;
    // 通过Object.values方法拿到对象中的所有值的数组集合
    let value = Object.values(myObject);
    // 返回一个对象
    return {
        // 定义迭代器每次执行的方法
        next(){
            // 如果当前循环没到最后一个
            if(index < that.list.length){
                // 继续循环
                return {
                    value: that.list[index++],
                    done: false
                }
            }else{
                // 如果循环完毕了,直接返回done=true表示循环完
                return {
                    value: undefined,
                    done: true
                }
            }
        }
    }
}

for(let v of myObject){
    console.log(v);
}
10 20 30 40 Array[10, 20, 30, 40]

通过上边的代码给对象增加迭代器,也能实现for…of的迭代对象,并且迭代器可以由我们自己来控制返回什么值。

通过上边的实例可以看出,for…in可以迭代任意类型,一般建议用在调试程序上,他能遍历出自身原型上自定义的属性和方法,也能遍历出继承的自定义属性和方法。
for…of是ES6新增的语法特性,主要是用来的带具有iterator接口的的类型,对象没有iterator接口所以不能使用for…of需要自己定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值