目录

  • 1.for...in
  • 2.for...of
  • 3.for...in和for...of的区别
  • 4.可枚举属性,可迭代对象
  • 1)可枚举属性
  • 2)可迭代对象
  • 5.迭代器,生成器
  • 6.数组,伪数组
  • 7.遍历map的方法


1.for…in

for...in循环遍历的是可枚举属性包括原型链上的可枚举属性

var obj = {a:1,b:2,c:3};
for(let key in obj){
	console.log(key);  // a  b  c
}

使用for...in也可以遍历数组,但是会出现以下问题

  • index索引为字符串型数字,不能直接进行几何运算
  • 遍历顺序有可能不是按照实际数组的内部顺序
  • 使用for...in会遍历数组所有的可枚举属性,包括原型。原型方法method和name属性都会被遍历出来,通常需要配合hasOwnProperty()方法判断某个属性是否为该对象的实例属性,来将原型对象从循环中剔除。
for (var key in myObj){
	//判断某个属性是否为myObj上的属性
	if(myObj.hasOwnProperty(key)){
		console.log(key)
	}
}

2.for…of

for...ofES6中新引入的特性,for...of的出现是为了方便迭代器的使用。
for…of语句在可迭代对象(包括Array,Map,Set,String,TypedArray,arguments对象等等)上创建一个迭代循环,对每个不同属性的属性值,调用一个自定义的有执行语句的迭代挂钩。
也就是说,for...of只可以循环可迭代对象的可迭代属性,不可迭代属性在循环中被忽略了。
for...of不可以遍历普通对象,想要遍历对象的属性,可以用for...in循环,或内建的Object.keys()方法。

const arr=['a','b','c']
for(let val of arr){
	console.log(val); // a b c
}

3.for…in和for…of的区别

  • for...in是es5的标准,遍历的是key(可遍历对象字符串数组key);for...in以任意顺序迭代对象的可枚举属性,一般用来遍历对象。
  • for...of是es6的标准,遍历的是value(可遍历对象字符串数组value);for...of语句遍历可迭代对象定义要迭代的数据,一般用于遍历数组的value
let arr = ['a', 'b', 'c']
//下面的两个for循环等价
for(var key in arr){
	console.log(arr[key]);
}
for(var value of arr){
	console.log(value);
}
//这个例子就可以看出来for...in和for...of的区别了
//在对象和数组的原型上挂载方法
Object.prototype.objMethod = function () {}; 
Array.prototype.arrMethod = function () {};
let arr = [3,5,7]
//在数组上挂载对象
arr.foo = "hello";
for(let i in arr){
	console.log(i);  //0, 1, 2, "foo", "arrMethod", "objMethod"
}
//可以看到对于array的不可迭代元属性objMethod,arrMethod
//和实例属性foo,在循环中被忽略;
for(let i of arr){
	console.log(i); //3, 5, 7
}

4.可枚举属性,可迭代对象

可枚举属性可迭代对象是数据循环的两个属性。

1)可枚举属性

可枚举对象的一个定义特征是,当我们通过赋值运算将属性赋值给对象时,我们将内部可枚举标志(enumerable)设置为true。这是默认值。我们可以通过将其设置为false来更改此行为。

const users = {}
users.languages = 'Javascript'
Object.getOwnPropertyDescriptor(users,'language')
//output
//{value:'Javascript',writable:true,enumerable:true,configurable:true}

//在循环中对我们使用的属性进行更多的控制
Object.defineProperty(users,'role',{value:'Admin',writable:true,enumerable:false})

for(const item in users){
	console.log(item) //languages
}

2)可迭代对象

如果一个对象定义了它的迭代行为,那它是可迭代的。
js中可迭代的内置对象包括Array,String, Set和Map对象等。
不可迭代,因为它没有指定iterator方法。
在js中,所有可迭代对象都是可枚举对象,但并非所有可枚举对象都是可迭代对象。

5.迭代器,生成器

生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。

6.数组,伪数组

伪数组定义:

  1. 拥有length属性
  2. 按照索引的方式存储数据
  3. 不具有数组所具有的方法

伪数组就像数组一样有length属性,也有0,1,2,3等属性的对象,看起来就像数组一样,但不是数组,比如。

var fakeArr = {
	length:3,
	"0":"first",
	"1":"second",
	"2":"third"
}
for(var i=0; i < fakeArr.length; i++){
	console.log(fakeArr[i]);  // first second third
}

7.遍历map的方法

const m = new Map([
    ["a",1],
    ["b",2],
    ["c",3]
])
//1.遍历键值对
for(let item of m){
    console.log(item)
}
//2.遍历键值对
for(let item of m.entries()){
    console.log(item)
}
//2.遍历map的键值
for(let key of m.keys()){
    console.log(key)
}
//4.遍历map的值
for(let value of m.values()){
    console.log(value)
}
//5.使用forEach(),无返回值
m.forEach((val,key) => console.log(`${key} => ${val}`))