WangXiZhu / fe-storage

这是平时自己的学习资料
0 stars 2 forks source link

for..in vs for..of #14

Open WangXiZhu opened 7 years ago

WangXiZhu commented 7 years ago

原文链接

for in

javascript中最基本的遍历方法非for循环莫属了。它需要3个表达式,一个变量声明,一个每次循环前都需要计算的表达式,一个每次循环结束都需要计算的表达式。 下面这个for循环将会 console.log 数组中的每一个元素。

const array = ['a', 'b', 'c', 'd'];

for (let i = 0; i < array.length; i++) {  
  console.log(array[i]);
}

// Result: a, b, c, d

除了 for循环以外,还有其他两个 for遍历方法, for..in 和 for..of

for..in

for..in 是用来遍历一个拥有可遍历 属性的对象。所以它可以用于所有具有这些属性的对象(而不仅仅通过 Object()s创建的)。

可枚举是定义一个对象拥有Enumerable,值为true的属性。 基本上,如果是enumerable,属性是“可枚举”。 我们可以使用 property.enumerable来判断是否一个属性是可枚举的,它将会返回true或者false。

for..in的代码如下

  for (variable in enumerable) {  
    // do stuff
  }

例如,为了循环打印该对象的所有值,我们可以使用下面方式

const obj = {  
    a: 1,
    b: 2,
    c: 3,
    d: 4
}

for (let key in obj) {  
    console.log( obj[key] )
}

// Result: 1, 2, 3, 4

for..in 和对象

for..in方法可以直接让我们遍历对象的键(keys)和值(values),因为对象不能使用能够遍历数组的方法 forEach.

for..in 和数组

数组的值对应的“键”是数字下标。所以,这些下标能够遍历的属性,其实就像对象的键,只是它们用整数代替了字符串。

这意味着我们能够通过使用for..in数组来检索它们的下标遍历数组所有的值。

const array = ['a', 'b', 'c', 'd'];

for (let index in array) {  
    console.log(array[index])
}

// Result: a, b, c, d

通常我们不建议使用 for..in来遍历数组,主要是因为不能保证在队列中遍历是否正确,但是这又是数组特别需要的。

for..in 和 string

字符串的每个字符都有一个下标。所以,它和数组类似都是可以枚举的,但对应的是数字。

const string = 'Ire Aderinokun';

for (let index in string) {  
    console.log(string[index])
}

// Result: I, r, e, , A, d, e, r, i, n, o, k, u, n

for..of

for..of 是在ES2015中引入的方法,为了遍历“可遍历集合”。这些对象有 [Symbol.iterator]属性。

[Symbol.iterator]属性允许我们遍历集合通过调用 [Symbol.iterator]().next()来获取该集合的下一个子类目。

const array = ['a','b','c', 'd'];  
const iterator = array[Symbol.iterator]();  
console.log( iterator.next().value )  
console.log( iterator.next().value )  
console.log( iterator.next().value )  
console.log( iterator.next().value )

// Result: a, b, c, d

for..of 包裹 [Symbol.iterator]来创建循环,语法如下

for (variable of iterable) {  
    // do stuff
}

for..of 和对象

for..of循环不能用来遍历对象,因为他们没有“可遍历性”,所以他们没有 [Symbol.iterator]属性。

for..of 和数组/字符串

数组和字符串能够使用循环,因为他们是可遍历的。这种方式用来在队列遍历数组更加可靠。

const array = ['a', 'b', 'c', 'd'];  
for (let item of array) {  
    console.log(item)
}
// Result: a, b, c, d

const string = 'Ire Aderinokun';  
for (let character of string) {  
    console.log(character)
}
// Result: I, r, e, , A, d, e, r, i, n, o, k, u, n

for..of 和 NodeLists

最后,一个真正对于 for..of有用的例子是遍历结点列表(NodeLists)。当我们在文档中查找元素的时候会得到一个结点列表,但并不是一个数组。意味着我们不能使用像遍历数组的方法 forEach.

那么怎么办呢,我们可以使用 Array.from() 把它转为数组,或者使用 for..of进行循环更加实用,它不仅仅是数组。

const elements = document.querySelectorAll('.foo');

for (let element of elements) {  
    element.addEventListener('click', doSomething);
}

对比

  for..in for..of
应用于 可枚举属性 可遍历集合
对象(Objects)
数组(Arrays) 是,但是不建议
字符串(Strings) 是,但是不建议