你不知道的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}

 

相关文章