for in循环
- 遍历一个对象自有的、继承的、可枚举的、非Symbol的属性
- 遍历的是数组的索引(即键名)
var a = ['l', 'j', 't'];
var s = new Set(['l', 'j', 't']);
var m = new Map([[1, 'l'], [2, 'j'], [3, 't']]);
a.length = 3
for(let b in a) { console.log(b) } // 0,1,2
问题来了~~
a.name = 'hello' // ['l', 'j', 't',name:'hello']
for(let b in a){ console.log(b) } // 0,1,2,name
a.length = 3 // ??????????还是3
原因:
- 使用非整数并通过方括号或点号来访问或设置数组元素时,所操作的并不是数组列表中的元素,而是数组对象的属性集合上的变量。
- 数组对象的属性和数组元素列表是分开存储的,并且数组的遍历和修改操作也不能作用于这些命名属性。
for of循环
- for of遍历的是数组内的元素,而不包括数组的原型属性method和索引name
- 具有iterable类型的集合可以通过新的for ... of循环来遍历。
var a = ['l', 'j', 't'];
for (let x of a) { // 遍历Array
console.log(x); // 是值:'l', 'j', 't'
}
var s = new Set(['l', 'j', 't']);
for (var x of s) { // 遍历Set
console.log(x); //是值:'l', 'j', 't'
}
var m = new Map([[1, 'l'], [2, 'j'], [3, 't']]);
for (var x of m) { // 遍历Map
console.log(x); // [1.'l'] [2,'j'] [3,'t']是元素 ,而for in无输出
}
forEach循环
- 对数组的每个元素执行一次提供的函数。
用法:
- 如果使用箭头函数表达式来传入函数参数,thisArg 参数会被忽略,因为箭头函数在词法上绑定了 this 值。
array.forEach(function(currentValue[,index,array]){
}[,thisArg])
var a = ['l', 'j', 't'];
a.forEach((item)=>{console.log(item)}) // 'l', 'j', 't'
Set没有索引,因此回调的前两个参数都是item
var s = new Set(['l', 'j', 't']);
s.forEach((item,index)=>console.log(item,index)) // 'l', 'j', 't'
Map的回调参数是value,key,map
var m = new Map([[1, 'l'], [2, 'j'], [3, 't']]);
m.forEach(item=>console.log(item)) // 'l' 'j' 't'
总结
foreach 和map的区别:
-
forEach()返回值是undefined,不可以链式调用。
-
map()返回一个新数组,原数组不会改变。
-
没有办法终止或者跳出forEach()循环,除非抛出异常,所以想执行一个数组是否满足什么条件,返回布尔值,可以用一般的for循环实现,或者用Array.every()或者Array.some();
-
Set没有索引,因此callback回调的前两个参数都是item
-
Map的回调参数是value,key,map
-
Set和Map无法使用map
var s = new Set(['l', 'j', 't']);
s.map((item,sameitem,s)=>console.log(item,sameitem,s))
// Uncaught TypeError: m.map is not a function
var m = new Map([[1, 'l'], [2, 'j'], [3, 't']]);
m.map((v,k,m)=>console.log(v,k,m))
// Uncaught TypeError: m.map is not a function