for...in
和for...of
的区别
- [ ]
for...in
是ES5的标准,该方法遍历的是对象的属性名称(key:键名)。一个Array对象也是一个对象,数组中的每个元素的索引被视为属性名称,所以在使用for...in
遍历Array时,拿到的是每个元素索引
- 一般用于遍历对象自身的和继承的可枚举属性。以及对象从构造函数原型中继承的属性。对于每个不同的属性,语句都会被执行。
- 不建议使用for in 遍历数组,因为输出的顺序是不固定的。
- 如果迭代的对象的变量值是null或者undefined, for in不执行循环体,建议在使用for in循环之前,先检查该对象的值是不是null或者undefined
for…in
语句以原始插入顺序迭代对象的可枚举属性(只能迭代出可枚举的属性,可枚举属性【js自定义属性】/不可枚举属性【对象的内置属性,如数组的length 就是一个内置属性,所以for…in遍历不出来】)。
-for…in
的原理是: ():返回给定对象所有可枚举属性的字符串数组
-
for...of
是ES6的标准,该方法遍历的是对象的属性所对应的值(value:键值)。所以它用来遍历数组时得到每个元素的值
- for…of 语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
- for…of 语句遍历可迭代对象定义要迭代的数据(非自定义属性)
- for…of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象、Generator 对象,以及字符串。
for...in
和for...of
的使用测试
使用两个方法对Array,Set,Map做测试
var a = ['A','B','C'];
var s = new Set(['A','B','C']);
var m = new Map([[1:'x'],[2:'y'],[3,'z']]);
//遍历数组
for(var x of a){
alert(x);//输出的是值 A B C
}
for(var x in a){
alert(x);//输出的是下标 0 1 2
}
//遍历Set集合
for(var x of s){
alert(x);//输出的是Set集合每个元素的值 A B C
}
for(var x in s){
alert(x);// 不起作用,不能使用for...in循环遍历Set集合
}
//遍历Map集合
for(var x of m){
alert(x[0]+"="+x[1]);//既可以拿到键名,也可以拿到键值,输出的是值 A B C
}
for(var x in m){
alert(x[0]+"="+x[1]);//for...in循环不能用于遍历Map
}
for...in
和for...of
遍历数组和对象
- 遍历对象:
var s={a:1,b:2,c:3};
var s1=Object.create(s);
for(var prop in s1){
console.log(prop);//a b c
console.log(s1[prop]);//1 2 3
}
for(let prop of s1){
console.log(prop);//报错如下 Uncaught TypeError: s1 is not iterable
}
for(let prop of Object.keys(s1)){
console.log(prop);// a b c
console.log(s1[prop]);//1 2 3
}
- 遍历数组
var arr=['a','b','c'];
arr.hobby = 'foosball';
for(let i in a){
console.log(i); //0 1 2 hobby
console.log(a[i]); //a b c foosball
}
for(let i of a){
console.log(i); //a b c
}
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
arr.hobby = 'foosball';
for (let i in arr) {
console.log(i); // 0, 1, 2, "hobby", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); //0, 1, 2, "hobby"
}
}
for (let i of iterable) {
console.log(i); // 'a', 'b', 'c'
}
将objCustom属性和arrCustom属性添加到和。由于继承和原型链,对象arr继承属性objCustom和arrCustom。使用hasOwnProperty() 来检查,证明属性arrCustom和objCustom是继承的。由此可见,for…of循环的是的是可迭代对象的value(值),in循环的是可迭代对象的key(属性),for…of循环不能循环普通的对象,对普通对象的属性遍历推荐使用for…in。
但是非要使用for…of来循环对象,并不是不可以。此时就要结合()进行使用:
for(var key of Object.keys(arr)){
//使用()方法获取对象key的数组
console.log(arr[key]);
}