在javascript中,for in是ES5标准,遍历key. for of是ES6标准,遍历value.本文从Array,Object和string三个维度来讲解 for…in和for…of的区别。
1,使用for-in可以遍历数组,但是会存在以下问题:
.index索引为字符串型数字(注意,非数字),不能直接进行几何运算。
.遍历顺序有可能不是按照实际数组的内部顺序(可能按照随机顺序)。
.使用for-in会遍历数组所有的可枚举属性,包括原型。通常需要配合hasOwnProperty()方法判断某个属性是否该对象的实例属性,来将原型对象从循环中剔除。
Array.prototype.name = 'world';
let myArray = [1, 2, 10, 30, 100];
myArray.type='数组';
for(let index in myArray){
console.log(index);
}
output:
0
1
2
3
4
type
name
Array.prototype.name = 'world';
let myArray = [1, 2, 10, 30, 100];
myArray.type='数组';
for(let index in myArray){
if (myArray.hasOwnProperty(index)) {
console.log(index);
}
}
output:
0
1
2
3
4
type
2,自ES5发布后也可以使用forEach来遍历数组,forEach仅遍历写在方括号里面的元素,且可以同时对key和value操作,key的类型为number。
注:在for、for-in中,break和continue可以正常执行并且达到想到的结果,但是return 不能正常执行。在forEach、map、filter中break和continue不能正常执行,return仅仅跳出当前循环,不会跳出整个函数。
Array.prototype.name = 'world';
let myArray = [1, 2, 10, 30, 100];
myArray.type='数组';
myArray.forEach((item, index) => {
console.log(index);
})
output:
0
1
2
3
4
let myArray = [1, 2, 10, 30, 100];
function f() {
myArray.forEach((item, index) => {
if (index === 3) {
return
}
console.log(index);
})
}
f();
console.log('done');
output:
0
1
2
4
done
3,for-of可以简单、正确地遍历数组,这是最简洁、最直接的遍历数组元素的语法。完美地避开了for-in循环的所有缺陷。与forEach()不同的是,它可以正确响应break、continue和return语句。
Array.prototype.name = 'world';
let myArray = [1, 2, 10, 30, 100];
myArray.type='数组';
function f() {
for (let item of myArray) {
if (item === 10) {
continue
}
console.log(item);
}
}
f();
console.log('done');
output:
1
2
30
100
done
几乎所有的 JavaScript对象都是 Object的实例;一个典型的对象继承了 Object.prototype的属性(包括方法),尽管这些属性可能被覆盖。 但是有时候可能故意创建不具有典型原型链继承的对象,比如通过Object.create(null)创建的对象,或者通过Object.setPrototypeOf方法改变原型链。
let aa = {
name: 'xiaoming',
age: 18
};
let bb = {
address: 'shanghai',
phone: 1778282882828
};
Object.setPrototypeOf(aa, bb);
for (let key in aa) {
console.log(key);
}
output:
name
age
address
phone
等价于
let aa = {
name: 'xiaoming',
age: 18
};
Object.prototype.address = 'shanghai';
Object.prototype.phone = '1778282882828';
for (let key in aa) {
console.log(key);
}
output:
name
age
address
phone
Object.keys() :返回对象自身的所有可枚举的属性的键名
let aa = {
name: 'xiaoming',
age: 18
};
let bb = {
address: 'shanghai',
phone: 1778282882828
};
Object.setPrototypeOf(aa, bb);
for (let key of Object.keys(aa)) {
console.log(key);
}
output:
name
age
所以for in更适合遍历对象,不要使用for in遍历数组。
类似于Array和Object,for…in和for…of用法如下,String本身没有forEach方法:
String.prototype.name = 'welcome';
let str = 'hello world';
for (let key in str) {
console.log(key);
}
output:
0
1
2
3
4
5
6
7
8
9
10
name
String.prototype.name = 'welcome';
let str = 'hello world';
for (let value of str) {
console.log(value);
}
output:
h
e
l
l
o
w
o
r
l
d