美文网首页
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正确遍历啦!

相关文章

  • &和&&,| 和 || 的区别

    &不管前面的条件是否正确,后面都执行 &&前面条件正确时,才执行后面,不正确时,就不执行,就效率而言,这个更好。 ...

  • &和&&, |和||的区别

    &和&&的含义一样, 表示逻辑与(and), 只有第一个表达式和第二个表达式都为 true 时, 整个运算结果才为...

  • &&和&,|和||的区别

    1 &&和&的区别 1 单&时,无论左边真假,右边都会进行计算 2 双&&时,只有左边为真时,右边才会进行计算,左...

  • null 和 undefined 的区别 ==和===的区别

    1.null 和 undefined 的区别 undefined 为变量未定义的值undefined表示"缺少值"...

  • is和 == 的区别

    为什么有时写代码 is 和 == 的结果相同,有的不相同呢? 分析: 官方文档中说 is 表示的是对象标示符(ob...

  • is和==的区别

    is 和 == 的区别 id()官网描述 def id(*args, **kwargs): # real sign...

  • *和**的区别

    **两个乘号就是乘方,比如2**4,结果就是2的4次方,结果是16 一个乘号*,如果操作数是两个数字,就是这两个数...

  • ${}和#{}的区别

    ${} 注入什么就是什么,且如果是简单类型的值需要用 value 来接收#{} 将传入的数据都当成一个字符串,会对...

  • is和==的区别

    is 是比较两个引用是否指向了同一个对象(引用比较)。 == 是比较两个对象是否相等。

  • .和..的区别

    .指的是当前目录; ..指的是上级目录; cd .. 进入上级目录 open ..打开上级目录; cd .进入本级...

网友评论

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

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