Open trayvonRen opened 4 years ago
最近在刷题的时候,经常会执行遍历的操作。 所以整理一下 JavaScript 遍历各种方法。
遍历器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。 可以使用 JavaScript 模拟 Iterator 的实现
function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } }; }
Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环。
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。 原生具备 Iterator 接口的数据结构如下。
for(let i = 0; i < arr.length; i++) { ... }
let i = arr.length; while(i--) { ... }
forEach() 方法对数组的每个元素执行一次提供的函数。 无返回值,不会改变数组。
let arr = [1,5,8,9] arr.forEach(item => { ... })
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
let arr = [1,5,8,9] let newArray = arr.map(item => { ... })
let arr = [1,5,8,9] for(let item of arr) { ... }
let str = 'abcdefg'; let strL = str.length; for(let i = 0; i < strL; i++) { console.log(str[i]) }
let str = 'abcdefg'; for(let item of str) { console.log(item) }
for...in 循环会遍历除 Symbol 以外的可枚举属性(包括它的原型链上的可枚举属性)。
for...in 循环也可以遍历数组 但不能保证for ... in将以任何特定的顺序返回索引,所以应该避免使用它遍历数组。 let obj = Object.create({ height: 200 })
for...in 循环也可以遍历数组 但不能保证for ... in将以任何特定的顺序返回索引,所以应该避免使用它遍历数组。
let obj = Object.create({ height: 200 })
obj.name = 'rcw'; obj.age = 100; obj[Symbol('money')] = 100;
for(let item in obj) { console.log(item, obj[item]) } //name rcw //age 100 //height 200
### 使用 Object.keys() 和 Object.values() 遍历 Object.keys() 方法会返回一个由一个给定对象的自身除 Symbol 以外可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。 ```js let obj = Object.create({ height: 200 }) obj.name = 'rcw'; obj.age = 100; obj[Symbol('money')] = 100; console.log(Object.keys(obj)) // [ 'name', 'age' ]
Object.values()方法返回一个给定对象自身除 Symbol 以外的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
let obj = Object.create({ height: 200 }) obj.name = 'rcw'; obj.age = 100; obj[Symbol('money')] = 100; console.log(Object.values(obj)) // [ 'rcw', 100 ]
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
let obj = {}; obj.name = 'rcw'; obj.age = 100; obj.__msg = 'no enumerable'; Object.defineProperty(obj, '__msg', { enumerable: false }) console.log(Object.getOwnPropertyNames(obj)); //[ 'name', 'age', '__msg' ]
最近在刷题的时候,经常会执行遍历的操作。 所以整理一下 JavaScript 遍历各种方法。
遍历器
遍历器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
Iterator 的作用:
Iterator 的工作流程:
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
可以使用 JavaScript 模拟 Iterator 的实现
for ... of 循环
Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环。
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。 原生具备 Iterator 接口的数据结构如下。
数组
常规方法 for, while 循环
数组方法 forEach, map
forEach() 方法对数组的每个元素执行一次提供的函数。 无返回值,不会改变数组。
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
for ... of
字符串
for while 循环
for .. of
对象
for ... in
for...in 循环会遍历除 Symbol 以外的可枚举属性(包括它的原型链上的可枚举属性)。
obj.name = 'rcw'; obj.age = 100; obj[Symbol('money')] = 100;
for(let item in obj) { console.log(item, obj[item]) } //name rcw //age 100 //height 200
Object.values()方法返回一个给定对象自身除 Symbol 以外的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
getOwnPropertyNames
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
总结