美文网首页
for in 和 for of 的区别

for in 和 for of 的区别

作者: 灯下草虫鸣314 | 来源:发表于2020-06-28 12:00 被阅读0次

    for infor of 是js中常用的遍历方法。但是两者有什么区别呢?
    今天我们就来讨论下两者的区别。

    遍历数组

    1. for in 是ES5的语法标准,而for of则是ES6语法标准。
    const arr = ['a', 'b', 'c']
    for(let i in arr){
        console.log(i)
        // '0', '1', '2'
    }
    for(let i of arr){
        console.log(i)
        // a, b, c
    }
    

    通过上述代码我们可以发现for in遍历的是下标,而for of遍历的是属性值
    而且。for in所遍历的下标是Strign类型而不是Number类型。

    1. for in 遍历时可以遍历到当前数组的所有属性名和方法名。包括其原型链上定义的属性名和方法名。如下代码:
    const arr = ['a', 'b', 'c']
    arr.name = 'arr'
    arr.getName =  function(){
      return this.name
    }
    arr.__proto__.constructor.prototype.sayHello = function(){
      return 'hello'
    }
    arr.__proto__.constructor.prototype.parentName = 'say uncle'
    for(let i in arr){
      if(arr.hasOwnProperty(i)){
        console.log('ownProperty',i)
        // '0', '1', '2', 'name', 'getName'
      }else{
        console.log('not ownProperty',i)
        // 'sayHello', 'parentName'
      }
    }
    

    而使用for of遍历时则不会遍历原型链上的属性和方法且不会遍历定义在数组上的属性和方法。
    代码如下:

    const arr = ['a', 'b', 'c']
    arr.name = 'arr'
    arr.getName =  function(){
      return this.name
    }
    arr.__proto__.constructor.prototype.sayHello = function(){
      return 'hello'
    }
    arr.__proto__.constructor.prototype.parentName = 'say uncle'
    for(let i of arr){
      console.log(i)
      // 'a', 'b', 'c'
    }
    

    遍历对象

    1. 使用for in遍历对象会遍历对象原型链的方法名和属性名,for in 循环实际是为循环可枚举(enumerable)对象而设计的
    const obj = {
      name:'uncle',
      gender: 'male',
      age:12,
    }
    obj.hobby = 'coding'
    obj.getName = function(){
      return this.name;
    }
    obj.__proto__.constructor.prototype.sayHello = function(){
      return "hello"
    }
    for(let i in obj){
      if(obj.hasOwnProperty(i)){
        console.log('ownProperty',i)
        // name, gender, age, hobby, getName
      }else{
        console.log('not ownProperty',i)
        // sayHello
      }
    }
    

    而使用 for of 遍历对象则会报错

    for(let i of obj){
      console.log(i)
    }
    // error Uncaught TypeError: obj is not iterable
    

    这是为什么呢?
    这是因为能够被for of正常遍历的数据类型都需要实现一个遍历器Iterator。而数组、字符串、Set、Map结构,早就内置好了Iterator(迭代器),它们的原型中都有一个Symbol.iterator方法,而Object对象并没有实现这个接口,使得它无法被for of遍历。

    我们可以通过为Object实现一个Iterator来使Object可以使用正常for of遍历

    Object.prototype[Symbol.iterator] = function() {
      let _this = this
      let index = 0
      let length = Object.keys(_this).length
      return {
          next:() => {
              let value = _this[Object.keys(_this)[index]]
              let done = (index >= length)
              index++
              return {value,done}
          }
      }
    }
    
    for(let i of obj){
      console.log(i)
    }
    

    这样对象就可以使用for of正确遍历啦!

    相关文章

      网友评论

          本文标题:for in 和 for of 的区别

          本文链接:https://www.haomeiwen.com/subject/cvwifktx.html