const obj = {
a : 1,
b: 2,
c: 3
}
for( let i in obj){
console.log(i);
// a
// b
// c
}
for( let i of obj){
console.log(i);
// TypeError: obj is not iterable
}
const arr = ['a', 'b', 'c']
for( let i in arr){
console.log(i);
// 0
// 1
// 2
}
for( let i of arr){
console.log(i);
// a
// b
// c
}
const arr2 = ['a', 'b']
// 手动给 arr数组添加一个属性
arr2.name = 'qiqingfu'
for( let i in arr2){
console.log('40----',i);
// 0
// 1
// name
}
for( let i of arr2){
console.log('47----',i);
// a
// b
}
结合以上例子可以分析出 for in
-
for in 循环返回的值都是数据结构的键值名
-
遍历对象返回的对象的 key值,遍历数组返回的是数组下标(key)
-
for in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键,如 arr2.name
-
特别情况下,for in 循环会以看起来任意的顺序遍历键名
-
什么是对象中的常规属性和排序属性
function Foo() {\
this[100] = 'test-100'\
this[1] = 'test-1'\
this["B"] = 'bar-B'\
this[50] = 'test-50'\
this[9] = 'test-9'\
this[8] = 'test-8'\
this[3] = 'test-3'\
this[5] = 'test-5'\
this["A"] = 'bar-A'\
this["C"] = 'bar-C'\
}\
var bar = new Foo()\
for(key in bar){\
console.log(`index:${key} value:${bar[key]}`)\
// index:1 value:test-1\
// index:3 value:test-3\
// index:5 value:test-5\
// index:8 value:test-8\
// index:9 value:test-9\
// index:50 value:test-50\
// index:100 value:test-100\
// index:B value:bar-B\
// index:A value:bar-A\
// index:C value:bar-C\
}
在上面代码中,利用构造函数Foo创建了一个bar对象,在构造函数中,给bar 设置了很多属性,数字属性和字母属性,然后我们枚举出来了bar对象中所有的属性,但打印出来的顺序,数字是按照数字大小的顺序打印的,设置的字符串属性是按照之前的设置的属性打印的,之所以会这样,是因为在 ECMAScript 规范中定义了 数字属性应该按照索引值大小升序排列,字符串属性根据创建的顺序升序排列 在这里,我们把对象中的数字属性称为 ** 排序属性** 在V8中被称为 elements, 字符串属性称为 常规属性 在v8中称为 properties
for in 特别适合遍历对象 使用for in 会遍历数组的所有可枚举属性,包括原型。
for of
for of 循环用来获取一对键值对中的值,而for in 取的是键名,for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name 一个数据结构只要部署了 Symbol.iterator属性,就被视为具有 iterator接口,就可以使用for of 循环
例1这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable for of 不同于foreach, 可以与break, continue, 和 return 配合使用, 也就是说可以随时退出循环
哪些数据结构部署了 Symbol.iteratoer属性了呢?
只要有 iterator 接口的数据结构,都可以使用 for of循环。 数组 Array Map Set String arguments对象 Nodelist对象, 就是获取的dom列表集合 -以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(...)、和解构赋值等操作
我也想让对象可以使用 for of循环怎么办?使用 Object.keys() 获取对象的 key值集合后,再使用 for of
let meals = {
mealA: 'Breakfast',
mealB: 'Lunch',
mealC: 'Dinner'
};
for (let key of Object.keys(meals)) {
let mealName = meals[key];
// ... do something with mealName
console.log(mealName, key);
// Breakfast mealA
// Lunch mealB
// Dinner mealC
}
使用for in会遍历数组所有的可枚举属性,包括原型。例如上栗的原型方法method和name属性