你不知道的JS系列 ( 39 ) - 对象遍历

for 循环可以遍历数组
var myArray = [1,2,3];
for(var i=0; i<myArray.length; i++) {
  console.log(myArray[i])
} // 1 2 3

ES5 增加了数组的辅助迭代器,包括 forEach(...)、every(...)、some(...)

forEach(...) 会遍历数组中的所有值并忽略回调函数的返回值
every(...) 会一直运行直到回调返回 false
some(...) 会一只运行直到回到函数返回 true



for..in 循环可以用来遍历对象的可枚举属性列表(包括原型链)。使用 for..in 遍历对象是无法直接获取属性值的,因为实际上遍历的是对象中的所有可枚举属性,需要手动获取属性值

 

遍历数组下标时采用的是数字顺序,但是遍历对象属性时的顺序是不确定的,因此,在不同环境中需要保证一致性时,一定不要相信任何观察到的顺序

 

那么如何遍历值而不是下标和属性呢,使用 ES6 增加的 for..of 循环语法
var myArray = [1,2,3];
for(var v of myArray){
  console.log(v)
}
// 1 2 3

for..of 循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的 next() 方法来遍历所有返回值

 

数组有内置的 @@iterator,因此 for..of 可以直接应用在数组上。我们使用内置的 @@iterator 来手动遍历数组
var myArray = [1,2,3];
var it = myArray[Symbol.iterator]();
it.next(); // {value: 1, done: false}
it.next(); // {value: 2, done: false}
it.next(); // {value: 3, done: false}
it.next(); // {done: true}
这里和值 ‘3’ 返回的是 done:false,咋一看好像很奇怪,你必须调用一次 next() 才能得到 done:true,从而确定完成遍历

 

普通的对象没有内置的 @@iterator,所以无法自动完成 for..of 遍历,当然,可以自己给任何想遍历的对象定义 @@iterator
var myObj = {
  a:2,
  b:3
}
Object.defineProperty(myObj, Symbol.iterator, {
  enumerable: false,
  writable: false,
  configurable: true,
  value: function() {
    var o = this;
    var idx = 0;
    var ks = Object.keys(o);
    return {
      next: function() {
        return {
          value: o[ks[idx++]],
          done: (idx > ks.length)
        }
      }
    }
  }
})

var it = myObj[Symbol.iterator]();
it.next(); // {value: 2, done: false}
it.next(); // {value: 3, done: false}
it.next(); // {done: true}

 

posted @ 2020-03-30 06:47  wzndkj  阅读(157)  评论(0编辑  收藏  举报