ES6迭代器(interator)和for...of...循环

发布时间:2019-08-09 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了ES6迭代器(interator)和for...of...循环脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

ES6迭代器(interator)和for...of...循环

或许在写ES6的代码的时候,你可能没有感觉有用过迭代器这个东西,可是ES6中的for...of...循环我们都不陌生,而for...of...循环的必要条件就是必须满足被循环的对象实现了迭代器接口才行。例子如下:

Example

@H_512_9@
VAR a = [1,2,3];
var b = {
    name:'arvin',
    age:30
}
for(var i of a){
    console.LOG(i);     // 结果依次是:1,2,3
}
for(var j of b){
    console.log(j);     // TyPEError: b[Symbol.ITerator] is not a function
}

代码解读对于上面代码的结果我们基本都知道,可是为什么是这个结果就不会很懂了。从代码的结果可以看出,for...of...循环可行的条件是需要被循环对象实现一个以Symbol.iterator为方法属性才行。而数组对象是默认实现了该方法的,所以并未报错。现在我们就来具体实现一下这个迭代器接口。

Example

var b = {
    name:'arvin',
    age:30
}
Object.definePRoperty(b, Symbol.iterator, {
    enumerable: false,
    writable: false,
    configurable: true,
    value: function () {
        var me = this;
        var idx = 0;
        var keys = Object.keys(me);
        return {
            next: function () {
                return {
                    value: me[keys[idx++]],
                    done: (idx > keys.length)
                }
            }
        }
    }
});

for(var j of b){
    console.log(j);     // 结果依次是:arvin,30
}
// 下面的代码类似上面的for...of...循环的内部实现
var c = b[Symbol.iterator]();
while(true){
  var newValue = c.next();
  if(newValue.done){
    break;
  }
  console.log(newValue.value)   // 结果依次是:arvin,30
}

代码解读:从上面的这个demo可以看出,ES6的迭代器是实现要求必须要实现一个Symbol.iterator接口,并且该接口要返回一个带有next方法的对象,而且该next方法必须包含至少两个值,value以及done,前者是迭代器的输出值,后者是判断迭代终止条件。下面附上一个通用上传迭代器的运用例子:

Example

let getUploadObj = {
    getActiveUploadObj (){
        try {
            return new ActiveXObject('TXFTNActiveX.FTNUpload');   // IE上传控件
        } catch (e) {
            return false;
        }
    },
    getFalshUploadObj () {  
        try {
            new ActiveXObject('ShockwaveFlash.ShockwaveFlash');   // Flash上传控件
            let str = '<object type="application/x-shockwave-flash"></object>';
            return $(str).appendTo($('body'));
        } catch (e) {
            return false;
        }
    },
    getFormUploadObj () {
        let str = '<input name="file" type="file" calss="ui-file"/>';   // 表单上传
        return $(str).appendTo($('body'));
    }
}

// 给对象getUploadObj定义iterator接口,上面演示过这段代码
// 这里可以通过工厂模式,抽象成一个专门给对象安装iterator接口的函数,这样就可以省却很多重复代码了。
Object.defineProperty(getUploadObj, Symbol.iterator, {
    enumerable: false,
    writable: false,
    configurable: true,
    value: function(){
        var o = this;
        var idx = 0;
        var ks = Object.keys(o);
        return {
            next: function(){
                return {
                    value: o[ks[idx++]],
                    done: (idx > ks.length)
                }
            }
        }
    }
});


function iteratorUploadObj (uploadObj){
    // 直接使用`for...of`遍历uploadObj对象
    for(let getUpload of uploadObj){
        let uploadObj = getUpload();
        if(uploadObj) return uploadObj;
    }
}

let uploadObj = iteratorUploadObj(getUploadObj);
console.log(uploadObj);  // [input, prevObject: Z.fn.init[1], context: undefined]

脚本宝典总结

以上是脚本宝典为你收集整理的ES6迭代器(interator)和for...of...循环全部内容,希望文章能够帮你解决ES6迭代器(interator)和for...of...循环所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。