1.什么是Iterator ? 遍历器(Iterator)它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。 Iterator 的作用有三个: 1.是为各种数据结构,提供一个统一的、简便的访问接口; 2.是使得数据结构的成员能够按某种次序排列; 3.是 ES6 创造了一种新的遍历命令
2.Iterator怎么用 ?
/** * 语法 * @variable 每次迭代中属性的值 * @iterable 被迭代枚举其属性的对象 */ for (variable of iterable) { //statements }
接下来一起来实践一下上面那些类型是不是真的可以用 ![]() // Array let arr = [10, 20, 30]; for (let value of arr) { value += 1; console.log(value); } // 11 // 21 // 31 // Map let map = new Map([["a", 1], ["b", 2], ["c", 3]]); for (let entry of map) { console.log(entry); } // ["a", 1] // ["b", 2] // ["c", 3] // Set let set = new Set([1, 1, 2, 2, 3, 3]); for (let value of set) { console.log(value); } // 1 // 2 // 3 // String let str = "boo"; for (let value of str) { console.log(value); } // "b" // "o" // "o" // TypedArray let typedArr = new Uint8Array([0x00, 0xff]); for (let value of typedArr) { console.log(value); } // 0 // 255 // arguments (function() { for (let argument of arguments) { console.log(argument); } })(1, 2, 3); // 1 // 2 // 3
那其他的类型用for of会怎么样? 比如一个普通的object类型
产品:“那我就要把for of用在对象上” 我:“对象不能用for of,你看这不都报错了嘛” 产品:“不听不听,你是不是不想做” 我:“好吧好吧,既然你想要用,那就满足你”
首先要了解遍历器 Iterator 的协议,传送门:MDN 迭代协议, 简而言之就是: 可迭代协议:可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 要成为可迭代对象, 一个对象必须实现
迭代器协议:迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。 只有实现了一个拥有以下语义(semantic)的
var obj = {
由此可见,普通对象不可直接使用for of,在[Symbol.iterator]属性上部署遍历器生成的方法后即可被for of使用(原型链上的对象具有该方法也可) 实际上,对象之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。 那知道了上面遍历器的协议,我们可以通过更简单的方式判定上述六种类型是否实现了遍历器接口了 Array.prototype.hasOwnProperty(Symbol.iterator); // true Set.prototype.hasOwnProperty(Symbol.iterator); // true Map.prototype.hasOwnProperty(Symbol.iterator); // true String.prototype.hasOwnProperty(Symbol.iterator); // true (function(){ console.log(arguments.hasOwnProperty(Symbol.iterator)) })(1,2,3) // true Uint8Array.prototype.__proto__.hasOwnProperty(Symbol.iterator) // true
3. 与for in的区别 可能看到for of 有人想到for in,那这两个长这么像,他两有啥区别呢。咱们一起来看看 var arr1 = ['a', 'b', 'c', 'd']; // 输出键名 for (let a in arr1) { console.log(a); // 0 1 2 3 }
4. 与其他循环的区别var arr = Array(10).fill(1); // forEach 循环,不能手动跳出循环 // for i 循环获取的是键名,而不是键值,因此不大适用于遍历数组
经比较,遍历对象用for in, 遍历数组用for of
实际上,要实现对象的Iterator接口还有更简洁的方法,就是使用generator let obj = { * [Symbol.iterator]() { yield 'hello'; yield 'world'; } }; for (let x of obj) { console.log(x); } // hello // world 看到这里有人又奇怪了,这个 * 号是个什么鬼? 答案是 Generator 函数,Generator 函数是一个普通函数,但是有两个特征。一是, 2020-06-09 11:23:51 |
|