for…in
for…in可以遍历对象属性列表,那么它是如何遍历属性值呢?
const array = [1, 2, 3, 4];
for (let i in array) {
console.log(i, array[i]);
}
//0 1
//1 2
//2 3
//3 4
从上面看出来,我们还是通过属性列表+对象的方式来获取属性值。实际上,这并不是在遍历属性值,而是间接的获取。
辅助迭代器
ES5中增加了一些数组的辅助迭代器。这里简单说一些怎么去迭代数组,不做深入研究。
forEach
const array = [1, 2, 3, 4];
array.forEach((item) => {
console.log(item); //1,2,3,4
});
some
//some
array.some((item) => {
console.log(item); //1,2,3,4
return false;
});
every
array.every((item) => {
console.log(item); //1,2,3,4
return true;
});
区别于some和very,forEach并没有返回值,而some和every去区别在于,some是当一个返回值为true的时候,就停止迭代,而every是当一个返回值为false的时候停止迭代。
使用for…in是无法直接获取对象属性值的。
那么如何直接遍历对象的属性值呢?偷偷的告诉你,ES6增加了一种用来遍历数组得for…of循环语法(如果对象本身也定义了迭代器的话也能遍历对象)
const array = [1, 2, 3, 4];
for (const i of array) {
console.log(i); //1,2,3,4
}
手动遍历
const array = [1, 2, 3, 4];
const it = array[Symbol.iterator]();
console.log(it.next());// {value: 1, done: false}
console.log(it.next());// {value: 2, done: false}
console.log(it.next());// {value: 3, done: false}
console.log(it.next());// {value: 4, done: false}
console.log(it.next());// {value: undefined, done: true}
我们使用ES6种的符号,Symblo.iterator来获取对象的内部属性@@iterator,返回的是一个函数。如你所见it.next()返回的是{value,done}的形式,done是一个布尔值,表示是否还有可在遍历的值,这里最后还返回一个{done:true}这有点奇怪,这个超出了今天所讲的范围,以后博主学到了再分享!
对象迭代
前几天博主在写代码的时候,突然就报错了,代码大概如下:
const obj = {
name: "陈志元",
age: 21,
height: 172,
weight: 118,
};
for (const i of obj) {
console.log(i); //obj is not iterable obj不可迭代!
}
欸?我当时就奇怪了,在我的映像中好像对象是可以迭代的欸?哈哈,应该是记混淆了!或者是其他对象内部实现了迭代器的!!
和数组不同的是,普通的对象没有内置@@iterator,所以无法自动完成for…of,但我们前面也说过,如果对象本身定义了迭代器也是可以遍历对对象的。
实现对象迭代器
const obj = {
name: "丁时一",
age: 21,
height: 170,
weight: 106,
};
Object.defineProperty(obj, Symbol.iterator, {
enumerable: true,
writable: false,
configurable: true,
value: function () {
const _this = this;
//获取所有键
const keys = Object.keys(_this);
let idx = 0;
return {
next: function () {
return {
value: _this[keys[idx++]],
done: idx > keys.length,
};
},
};
},
});
for (const i of obj) {
console.log(i);//丁时一 21 170 106
}
const it = obj[Symbol.iterator]();
console.log(it.next());//{value: "丁时一", done: false}
console.log(it.next());//{value: 21, done: false}
console.log(it.next());//{value: 170, done: false}
console.log(it.next());//{value: 106, done: false}
console.log(it.next());//{value: undefined, done: true}
这里呢我们使用Object.defineProperty定义了一个迭代器,并使用了闭包返回了一个函数next,当调用函数的时候,会返回当前的value和done。