有关遍历的那些事(for..of原理讲解)
//用来简写console.log function c(content) { console.log(content) } //遍历 var arr = [1, 2, 3, 4, 5] var obj = { name: xiaoli, age: 12 } //几种遍历方式 //数组遍历,除了常规的for 循环 // ES6新增的数组迭代器 arr.forEach(function(item) { console.log(item) }) //判断数组中是否每一项都大于3 返回结果为一个boolean值 arr.every(function(item) { return item > 3 }) //判断数组中是否有部分值<3,返回结果是一个Boolean值 arr.some(function(item) { return item < 3 }) //for in 无法直接获取属性值,需要手动获取 for (key in arr) { console.log(key + : + arr[key]) } //es6定义了for of 方法可以直接遍历属性值 for (item of arr) { console.log(item) } //对象遍历 //for in 会遍历包括原型链上的属性 for (key in obj) { console.log(key + : + obj[key]) } /* 接下来需要对迭代器的原理进行一个讲解 1、首先会向被访问对象请求一个迭代器对象 2、通过调用迭代器对象的next方法来遍历所有返回值 */ // 对象没有@@interator,所以无法完成for..of的遍历,但是我们可以给想遍历的对象定义一个@@intetator var myObject = { a: 3, b: 3 } Object.defineProperty(myObject, 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) } } } } }) //手动遍历myObject var it = myObject[Symbol.iterator](); c(it.next()) c(it.next()) c(it.next()) for (var item of myObject) { console.log(item) } //以上方法我们符号定义为可计算属性名,主要是为了让其不可枚举 //此外也可以在定义对象时进行声明 var obj_symbol = { "a": 9, "b": 9, [Symbol.iterator]: function() { var o = this; var idx = 0; var ks = Object.keys(o); return { next: function() { return { value: o[ks[idx++]], done: (idx > ks.length) } } } } } for (var item of obj_symbol) { console.log(item) }
for…of 和对象迭代器结合,就可以生成强大的对象操作工具,例如随机数组生成
var random = { [Symbol.iterator]: function() { return { next: function() { return { value: Math.random() } } } } } var random_pool = []; for (var n of random) { random_pool.push(n); //防止无限运行 if (random_pool.length === 100) break; } console.log(random_pool)