for...in
循环遍历的是可枚举属性
(包括原型链上的可枚举属性
)
var obj = {a:1,b:2,c:3};
for(let key in obj){
console.log(key); // a b c
}
使用for...in
也可以遍历数组,但是会出现以下问题
字符串型数字
,不能直接进行几何运算可能不是按照实际数组的内部顺序
for...in
会遍历数组所有的可枚举属性,包括原型。原型方法method和name属性都会被遍历出来,通常需要配合hasOwnProperty()
方法判断某个属性是否为该对象的实例属性,来将原型对象从循环中剔除。for (var key in myObj){
//判断某个属性是否为myObj上的属性
if(myObj.hasOwnProperty(key)){
console.log(key)
}
}
for...of
是ES6
中新引入的特性,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
}
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
}
可枚举属性
和可迭代对象
是数据循环的两个属性。
可枚举对象的一个定义特征是,当我们通过赋值运算将属性赋值给对象时,我们将内部可枚举标志(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
}
如果一个对象定义了它的迭代行为,那它是可迭代的。
js中可迭代的内置对象包括Array,String, Set和Map对象等。
不可迭代,因为它没有指定iterator方法。
在js中,所有可迭代对象都是可枚举对象,但并非所有可枚举对象都是可迭代对象。
生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。
伪数组定义:
length属性
伪数组就像数组一样有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
}
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}`))