ECMAScript之for...of与Iterator
2018-06-28 本文已影响0人
锋叔
先说for...of再说Iterator。
for...of循环
const arr = [{name:'a'},{name: 'b'},{name: 'c'}, {name:'d'}]
// 我们现在要取得abcd这四个值
// es5时普遍使用for循环
for(var i=0; i < arr.length; i++){
console.log(arr[i].name)
}
// => a b c d
// es6使用for...of循环
for(let item of arr){
console.log(item.name)
}
// => a b c d
// 偶尔实际操作中我们需要获取值的下标也就是index
for(let index of Object.keys(arr)){
console.log(index)
}
// => 0 1 2 3
谁更简单更容易理解?想想你当初理解for循环的时候你会感触更深!
entries,keys,values
- ES6 的对象、数组、Set、Map 都部署了以下三个方法,调用后都返回遍历器对象。
- entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
- keys() 返回一个遍历器对象,用来遍历所有的键名。
- values() 返回一个遍历器对象,用来遍历所有的键值。
const obj = {name:'a',sex:'man',job:'GD'}
var entries = Object.entries(obj)
console.log(entries) // => [["name", "a"],["sex", "man"],["job", "GD"]]
var keys = Object.keys(obj)
console.log(keys) // => ["name", "sex", "job"]
var values = Object.values(obj)
console.log(values) // => ["a", "man", "GD"]
const arr = [{name:'a'},{name: 'b'},{name: 'c'}, {name:'d'}]
var entries = Object.entries(arr)
console.log(entries) // => [ ["0", "a"], ["1", "b"], ["2", "c"], ["3", "d"]]
var keys = Object.keys(arr)
console.log(keys) // =>["0", "1", "2", "3"]
var values = Object.values(arr)
console.log(values) // => ["a", "b", "c", "d"]
for..of循环对象
const obj = {name:'a',sex:'man',job:'GD'}
// es5时普遍使用for...in循环
for(let key in obj){
console.log(key+'-'+Reflect.get(obj,key))
}
// => name-a
// => sex-man
// => job-GD
// es6使用for...of循环
for(let item of obj){
console.log(item.name)
}
// => Uncaught TypeError: obj is not iterable
报错咯!哈哈。看来是不支持循环普通对象的。如何才能支持呢?这个问题我后来研究了一整天发现都没办法解决!除非用上面的keys,entries,values方法组合使用。这是我觉得Interator的一个大缺陷!也就是for...in并不能被完全替代!
理解Interator
Interator是一种接口,为各种不同的数据结构(Array,Object,Set,Map,String...)提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员),也就是可以for...of循环。
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内。
特殊对象Interator实例
let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}
字符串Interator实例
let str= "Hello"
for (let item of str) {
console.log(item); // 'H', 'e', 'l','l','o'
}
// 这是没问题的但是我们可以利用Interator改变他。
str[Symbol.iterator] = function() {
return {
next: function() {
if (this._first) {
this._first = false;
return { value: "bye", done: false };
} else {
return { done: true };
}
},
_first: true
};
};
[...str] // ["bye"]
str // "hi"
总结
Interator无聊的设计!反正暂时没想到有什么用。for...of该支持的依旧支持,不支持的依旧不支持!shit.