在对数组和对象进行遍历的时候,经常用到两种方法:for in 和for of,让我们看看有什么区别。
for in
在对象中
Object.prototype.sayHello = function(){
console.log('Hello');
}
Object.prototype.str="world";
var myObj = {name:'lisi',age:35}
for(let index in myObj){
console.log(index);
}
//输出: name age str sayHello
// 返回的是对象的属性名,接着是对象原型的属性和方法
// 如果不想让其输出原型中的属性和方法,可以使用hasOwnProperty方法进行过滤
for(let index in myObj){
if(objTest.hasOwnProperty(index)){
console.log(index); // name age
}
}
//输出: name age
在数组中
Array.prototype.sayHello = function(){
console.log("Hello")
}
Array.prototype.str = 'world';
var myArray = [1,2,10,30,100];
myArray.name='数组';
for(let index in myArray){
console.log(index);
}
//输出: 0 1 2 3 4 name str sayHello
针对字符串
let str = 'study';
for(let index of str){
console.log(index);
}
//输出: 0 1 2 3 4
可以看出 for in应用于数组循环返回的是数组的下标、数组的属性和原型上的方法和属性,而for in 应用于对象循环返回的是对象的属性名和原型中的方法和属性。
使用for in也可以遍历数组,但是存在以下问题:
1.index索引为字符串型数字
2.遍历顺序有可能不是按照实际数组的内部顺序
3.使用for in 会遍历数组所有的可枚举属性,包括原型
for of
在对象中
Object.prototype.sayHello = function(){
console.log("Hello")
}
const myObject = {
name:'lisi',
age:35
}
for(let key of myObj){
console.log(key);
}
//输出: typeError
在数组中
Array.prototype.sayHello = function(){
console.log("Hello")
}
var myArray = [1,2,10,30,100];
for(let key of myArray){
console.log(key);
}
//输出: 1 2 10 30 100
for Of遍历的是数组元素值,确切的说叫做迭代,并且可以通过break、return false来中断循环
迭代字符串
let str = 'study';
for(let value of str){
console.log(value);
}
//输出 :s t u d y
迭代arguments类数组对象、set、Map、generators
// 迭代arguments类数组对象
(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3);
//输出 : 1 2 3
// 迭代NodeList这类DOM集合
let elements = document.querySelectorAll('body');
for (let element of elements) {
console.log(element.tagName);
}
//输出 : BODY
// 迭代 set
let setData = new Set([1, 1, 2, 2, 3, 3]);
for (let value of setData) {
console.log(value);
}
//输出 : 1 2 3
// 迭代Map
let mapData = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (let [key, value] of mapData) {
console.log(value);
}
//输出 : 1 2 3
for in 遍历数组,遍历的是数组的下标和数组的属性一级原型上的方法和属性。遍历对象,遍历的是对象的属性名和原型中的属性和方法,兼容性更好。 for of遍历数组的元素值,同时可遍历arguments类数组对象、set、Map、generators等。
for of 如何遍历对象?
刚刚的例子直接用for of不能遍历对象,因为普通对象没有Iterator,只有提供了Iterator接口的数据类型才可以使用for-of来遍历,同时ES6提供了Symbol.iterator属性,那么我们来简单实现一下:
- 遍历的对象是类数组
var obj = {
0:'one',
1:'two',
length: 2
};
obj = Array.from(obj);
for(var k of obj){
console.log(k)
}
- 如果不是类数组,添加[Symbol.iterator]
// 方法一
var obj = { a:1, b:2, c:3 };
obj[Symbol.iterator] = function*(){
var keys = Object.keys(obj);
for(var k of keys){
yield [k,obj[k]]
}};
for(var [k,v] of obj){
console.log(k,v);
}
// 方法二
var obj = {
a:1,
b:2,
c:3
};
obj[Symbol.iterator] = function(){
var keys = Object.keys(this);
var count = 0;
return {
next(){
if(count<keys.length){
return {value: obj[keys[count++]],done:false};
}else{
return {value:undefined,done:true};
}
}
}
};
for(var k of obj){
console.log(k);
}