一、遍历方式
1.for...in 循环
for...in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。
for...in 语句用于对数组或者对象的属性进行循环操作。
for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。
for...in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性,语句都会被执行。
for (variable in object) {...}
variable
在每次迭代时,将不同的属性名分配给变量。
object
被迭代枚举其属性的对象。
for...in 循环只遍历可枚举属性。像 Array和 Object使用内置构造函数所创建的对象都会继承自Object.prototype和String.prototype的不可枚举属性,例如 String 的 indexOf() 方法或 Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同。不能保证for ... in将以任何特定的顺序返回索引。for ... in循环语句将返回所有可枚举属性,包括非整数类型的名称和继承的那些。
因为迭代的顺序是依赖于执行环境的,所以数组遍历不一定按次序访问元素。因此当迭代访问顺序很重要的数组时,最好用整数索引去进行for循环(或者使用 Array.prototype.forEach() 或 for...of 循环)
var myTeam = new Array()
myTeam[0] = "liangsijie"
myTeam[1] = "mayun"
myTeam[2] = "mahuateng"
myTeam[3] = "wangjianlin"
myTeam.name = "向钱走吧"
for (var x in myTeam)
{
console.log(myTeam[x]);
}
2.for...of 循环
for … of循环是ES6引入的新的语法,用for … of循环遍历集合
for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。
for (variable of iterable) {
//statements
}
variable
在每次迭代中,将不同属性的值分配给变量。
iterable
被迭代枚举其属性的对象。
var myTeam = new Array()
myTeam[0] = "liangsijie"
myTeam[1] = "mayun"
myTeam[2] = "mahuateng"
myTeam[3] = "wangjianlin"
myTeam.name = "向钱走吧"
for (var onePersion of myTeam)
{
console.log(onePersion);
}
3.可迭代对象和枚举属性
可迭代对象有
- 1.
Array
- 2.
String
- 3.
Map
- 4.
Set
- 5.
arguments
- 6.
NodeList
判断一个对象是否具有可迭代能力,只有当对象具有Symbol.iterator
属性的时候才可以使用for...of
进行迭代Symbol.iterator是一个属性,而不是说iterator是Symbol的属性
//Array 是可迭代对象,那么它的原型就应该哟偶该属性,
Array.prototype[Symbol.iterator]===true
//或者它创建出来的对象的属性具有该属性
new Array()[Symbol.iterator]===true
可迭代不代表是一个迭代器,只有迭代器才具有next()
方法
let arr=new Array("a","b");
arr.next();
arr[Symbol.iterator].next();
//一个迭代器的实现
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
// 之后的所有调用
console.log(iterator.next()); // "{ value: undefined, done: true }"
// 将不可迭代对象转换为迭代对象
function Man(name ,age){
this.name=name;
this.age=age;
}
// 给对象原型赋值迭代器属性,对象将可迭代
Man.prototype[Symbol.iterator] = createIterator
function createIterator() {
const self = this;
const keys = Object.keys(self);
const len = keys.length;
let pointer = 0;
return {
//迭代器的next方法
next() {
const done = pointer >= len;
const value = !done ? self[keys[pointer++]]: undefined;
return {
done,
value
}
}
}
}
let obj = new Man("liangsijie",29);
let objIterator = obj[Symbol.iterator]();
console.log('===', objIterator.next());
for (const item of obj) {
console.log(item)
}
可枚举属性(enumerable)和propertyIsEnumerable()
枚举就是列举,可枚举属性就是可以列举的属性,直白一点就是可以用for in遍历到的属性。
可枚举属性会对那些操作产生影响
for…in
Object.keys()
JSON.stringify()