在ES中,遍历数据的时候会用到for…in/of的语法,比较一下两者的用法
for…of for…of是ES6的语法,用来遍历可迭代的对象(含有Symbol.iterator属性的对象)。像Array, Map, Set, 字符串等
简单使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const arr1 = ['a' , 'b' , 'c' ]for (const item of arr1){ console .log (item) } const map1 = new Map ()map1.set ('k1' , 'v1' ) map1.set ('k2' , 1 ) map1.set ('k3' , {'name' : 'kobe' }) for (const item of map1){ console .log (item) } const set1 = new Set ()set1.add ('hello' ) set1.add (100 ) set1.add ({'name' : 'kobe' }) const obj = {eat : () => {console .log ('eat' )}}set1.add (obj) for (const item of set1){ console .log (item) }
手动实现forOf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const forOf = (obj, cb ) => { let iterable, result console .log (obj, typeof obj[Symbol .iterator ]) if (typeof obj[Symbol .iterator ] !== 'function' ){ throw new TypeError ('params is not a iterable' ) } iterable = obj[Symbol .iterator ]() result = iterable.next () while (!result.done ){ cb && cb (result.value ) result = iterable.next () } } forOf ([1 ,2 ,3 ], (item ) => {console .log (item)})
实现遍历普通对象 由于普通对象没有Symbol.iterator属性,故不能使用for…of, 若要使用,则需要先处理
使用Object扩展方法 Object.keys()、Object.values()、Object.entries() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const obj = { name : 'kobe' , age : 18 , friends : [ { name : 'james' } ] } for (const item of Object .keys (obj)){ console .log (item) } for (const item of Object .values (obj)){ console .log (item) } for (const item of Object .entries (obj)){ console .log (item) }
生成器函数重新包装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const obj = { name : 'kobe' , age : 18 , friends : [ { name : 'james' } ] } function * entries (obj ) { for (let key of Object .keys (obj)){ yield [key, obj[key]] } } for (const item of entries (obj)){ console .log (item) }
在对象上添加Symbol.iterator属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const obj = { name : 'kobe' , age : 18 , friends : [ { name : 'james' } ] } obj[Symbol .iterator ] = function ( ){ const keys = Object .keys (this ) let i = 0 return { next : () => { let value = undefined , done = true if (i < keys.length ){ value = this [keys[i]] done = false i = i + 1 } return {value, done} } } } for (const item of obj){ console .log (item) }
for…in for…in是ES5的语法,用于遍历可枚举的对象,包括原型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 const obj = { name: 'kobe', age: 18, friends: [ { name: 'james' } ] } for(const key in obj){ console.log(key, '->', obj[key]) // name -> kobe age -> 18 friends -> [{'name': 'james'}}] } const obj2 = [1, 2, 3] for(const key in obj2){ console.log(key, '->', obj2[key]) // 0 - > 1 1 -> 2 2 -> 3 } Array.prototype.a = 123 for(const key in obj2){ console.log(key, '->', obj2[key]) // 0 - > 1 1 -> 2 2 -> 3 a -> 123 } // 不获取原型链上的属性 for(const key in obj2){ if (obj2.hasOwnProperty(key)){ console.log(key, '->', obj2[key]) // 0 - > 1 1 -> 2 2 -> 3 } }
小结 for in
遍历的是数组的索引(即键名),而for of
遍历的是数组元素值
for in
总是得到对象的key
或数组、字符串的下标
for of
总是得到对象的value
或数组、字符串的值
for...of
不能遍历普通Object对象