for in 循环详解

for…i 循环的作用

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

  • for...in 是为遍历对象属性而构建的,不建议与数组一起使用
  • 在处理有 key-value 数据,用于获取对接的 key,也就是获取键值
  • 只遍历可枚举属性。像 ArrayObject 使用内置构造函数所创建的对象都会继承自 Object.prototypeString.prototype 的不可枚举属性,这种是无法遍历的

语法:for (variable in object)

  • variable:在每次迭代时,variable 会被赋值为不同的属性名。
  • object:非 Symbol 类型的可枚举属性被迭代的对象。

使用示例

遍历一个带有 Symbol 的对象

const obj = {
  a: 'a',
  b: 'b',
  c: 'c',
  [Symbol('a')]: '我是 symbol',
}

for (let key in obj) {
  console.log('obj.' + key + ' = 我是' + obj[key])
}

结果如图:Symbol 并没有出现在遍历的结果当中

遍历带有不可枚举的属性

如下面的代码所示,我们在 obj 上加了两个属性,enumerableTrue 可枚举,notEnumerableTrue 不可枚举

const obj = {
  a: 'a',
  b: 'b',
  c: 'c',
  [Symbol('a')]: '我是 symbol',
}

Object.defineProperty(obj, 'enumerableTrue', {
  value: 'enumerableTrue',
  enumerable: true
})

Object.defineProperty(obj, 'notEnumerableTrue', {
  value: 'not-enumerableTrue',
  enumerable: false
})

for (let key in obj) {
  console.log('obj.' + key + ' = 我是' + obj[key])
}

结果如图所示:notEnumerableTrue 不可枚举的属性,没有在遍历的结果中

继承的枚举示例

如下代码,我们创建了一个构造函数 TestProtoType,并在其中声明了一个 name 属性,并将 TestProtoType 构造函数的原型绑定到了 obj 对象

const obj = {
  a: 'a',
  b: 'b',
  c: 'c',
  [Symbol('a')]: '我是 symbol',
}

Object.defineProperty(obj, 'enumerableTrue', {
  value: 'enumerableTrue',
  enumerable: true
})

Object.defineProperty(obj, 'notEnumerableTrue', {
  value: 'not-enumerableTrue',
  enumerable: false
})

function TestProtoType () {
  this.name = 'wfly'
}

TestProtoType.prototype = obj

const testProtoTypeObj = new TestProtoType();

for (let key in testProtoTypeObj) {
  console.log('testProtoTypeObj.' + key + ' = 我是' + testProtoTypeObj[key])
}

console.log('=======');

for (let key in testProtoTypeObj) {
  if (testProtoTypeObj.hasOwnProperty(key)) {
    console.log('testProtoTypeObj.' + key + ' = 我是' + testProtoTypeObj[key])
  }
}

console.log(testProtoTypeObj);

结果如图所示:对构造函数的实例进行遍历时,会输出其原型上的可枚举属性。如果只想输出是对象本身的使用 hasOwnProperty 即可

遍历数组

使用 for in 去遍历数组,得到的 key 就是数组的索引 index

const arr = [{ name: 'wfly' }, { name: 'fnn' }]
for (let key in arr) {
  console.log('obj.' + key + ' = 我是' + JSON.stringify(arr[key]))
}

for…in 如何中断循环

for in 中可以使用 break 或者 continue 去中断循环,不可以直接用 return 去中断循环

const obj = {
  a: 'a',
  b: 'b',
  c: 'c',
  [Symbol('a')]: '我是 symbol',
}

// 循环中断
for (let key in obj) {
  if (key === 'b') {
    break
  }
  console.log('obj.' + key + ' = 我是' + obj[key])
}

console.log('=============');

for (let key in obj) {
  if (key === 'b') {
    continue
  }
  console.log('obj.' + key + ' = 我是' + obj[key])
}

console.log('=============');

return 中断

return 不能直接中断循环,必须放在函数中

function test () {
  const obj = {
    a: 'a',
    b: 'b',
    c: 'c',
    [Symbol('a')]: '我是 symbol',
  }
  for (let key in obj) {
    if (key === 'b') {
      return
    }
    console.log('obj.' + key + ' = 我是' + obj[key])
  }
}

test()
  • 37
    点赞
  • 149
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wflynn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值