for..of
ES6新增了一个for..of循环,在迭代器生产的一系列值的循环。for..of循环的值必须是一个iterable。
var a = ["a", "b","c","d","e"]
for(var idx in a){
    console.log(idx)
}
// 0 1 2 3 4
for(var val of a){
    console.log(val)
}
// a b c d efor..in在数组a的键/索引上循环,for..of在a的值上循环。
ES6之前的代码
var a = ["a", "b","c","d","e"]
for(var val, ret, it = a[Symbol.iterator]();(ret=it.next()) && !ret.done){
    val = ret.value
    console.log(val)
}
// a b c d e在底层,for..of循环向iterable请求一个迭代器,然后反复调用这个迭代器把它产生的值赋给循环迭代变量。
JavaScript默认为iterable的标准内建值包括:
ArrayStringsGeneratorsCollections/TypedArrays
字符串迭代方式
for(var c of "hello"){
    console.log(c)
}
// h e l l o 原生字符串值被强制类型转换到等价的String封装对象中,它是一个iterable
for(XYZ of ABC)
对于XYZ这个位置既可以是赋值表达式,也可以是声明。下面看个赋值表达式的例子:
var o = {}
for(o.a of [1,2,3]){
    console.log(o.a)
}
o // {a:3}
for({x:o.a} of [{x:1},{x:2},{x:3}]){
    console.log(o.a)
}
o // {a:3}通过break,continue,return提前终止循环。
自定义迭代器
通过对底层的了解,for..of向iterable请求一个迭代器,然后反复调用这个迭代器把它产生的值赋给循环迭代变量。那么我可以自定义一个iterable。
var o = {
    [Symbol.iterator](){
        return this
    },
    next(){
        if(!val){
            val = 1
        }else{
            val ++
        }
        return {value:val, done:val== 6}
    }
}
for(var val of o[Symbol.iterator]()){
    console.log(val)
}由此可见,自定义迭代器满足两个条件,[Symbol.iterator]属性,返回的对象中有next方法,next方法返回值必须是{value:xx,done:xx}的形式,如果遇到done:true,则循环结束。
结语:以上就是for..of循环的全部内容,它可以循环可迭代对象。