循环大集合

235 阅读2分钟

for in循环

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 传送门

  • 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循环

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