(1)Iterator
他是一个接口,为各种不同的数据结构提供统一访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作
遍历过程
- 创建一个指针对象,指向当前结构的起始位置
- 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员
- 第二次调用指向第二个成员
- 不断调用next方法,直到指向他数据结构的结束位置
- 每一次调用next方法,都会返回数据结构的当前成员信息。就是返回包含value和done两个属性的对象,其中,value是当前成员的值,done是一个布尔值,表示遍历是否结束
原生具备Iterator接口的结构
- Array
- Map
- Set
- String
- TypedArray
- 函数的arguments对象
- NodeList对象
(2)for...of...
一个数据结构只要部署了Symbol.iterator属性,就会被视为具有iterator接口,就可以用for...of循环遍历他的成员
对于普通的对象使用for...of遍历,会报错
解决方法
使用Object.keys方法将对象的键名生成一个数组,然后遍历这个数组。
优点
- 遍历数组时,相比于其他方法更简洁
- 与forEach方法相比,他可以与break,continue,return结合使用
for...in...
for..in循环会遍历原型链上可以枚举的属性,包括原型链上的方法
for...in...的缺点
- for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。
- 某些情况下,for...in循环会以任意顺序遍历键名。
- 数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”
- 不适合遍历数组
- for...in 循环只遍历可枚举属性
(3)Object.definedPeoperty()
可以用来新增对象的一个属性,也可以用来修改一个对象的属性,返回这个对象
Object.defineProperty(obj, prop, descriptor)
descriptor
- configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false
- enumerable:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。默认为false
- value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为undefined
- writable: 当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。默认为false
Object.getOwnPropertyDescriptor(obj, 'name') //查看一个属性的描述
(4)Object.getOwnPropertyNames()
方法返回一个数组,成员是参数对象自身的全部属性的属性名,不管该属性是否可遍历。