Skip to content

4、迭代器模式

js
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
        }
    }
}
js
var Iterator = function(obj){
    var current = 0;
    var next =function (){
        current+=1
    }
    var isDone = function (){
        return current >=obj.length;
    }
    var getCurrItem = function (){
        return obj[current]
    }
    return {
        next:next,
        isDone:isDone,
        getCurrItem:getCurrItem,
        length:obj.length,
    }
}
  • es 与设计模式 迭代器函数原理基本相同,就是将遍历从代码中分离,不再手动控制
js
var each = function( ary, callback ){
    for ( var i = 0, l = ary.length; i < l; i++ ){
        callback.call( ary[i], i, ary[ i ] );  // 把下标和元素当作参数传给callback函数
        // if ( callback( i, ary[ i ] ) === false ){    // callback的执行结果返回false,提前终止迭代
        //     break;
        // }
    }
};
each( [ 1, 2, 3 ], function( i, n ){
    alert ( [ i, n ] );
});
js
var getActiveUploadObj = function(){
    try{
        return new ActiveXObject( "TXFTNActiveX.FTNUpload" );    // IE上传控件
    }catch(e){
        return false;
    }
};

var getFlashUploadObj = function(){
    if ( supportFlash() ){     // supportFlash函数未提供
        var str = '<object type="application/x-shockwave-flash"></object>';
        return $( str ).appendTo( $('body') );
    }
    return false;
};
var getFormUpladObj = function(){
    var str = '<input name="file" type="file" class="ui-file"/>';  // 表单上传
    return $( str ).appendTo( $('body') );
};

var iteratorUploadObj = function(){
    for ( var i = 0, fn; fn = arguments[ i++ ]; ){
        var uploadObj = fn();
        if ( uploadObj ! == false ){
            return uploadObj;
        }
    }
};

var uploadObj = iteratorUploadObj( getActiveUploadObj, getFlashUploadObj, getFormUpladObj );

// var uploadObj = null
// for(const fn of [getActiveUploadObj, getFlashUploadObj, getFormUpladObj]){
//     var uploadObj = fn();
//         if ( uploadObj ! == false ){
//             uploadObj = uploadObj //获取
//             break //关闭
//         }
// }
js
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}

1、for of 实际就是调用的迭代器函数 2、[1,2,3] 数组使用内建的迭代器函数 3、for...of 可以由break, throw, continue 迭代器关闭 (或return终止 ?) 4、生成器 4.1 调用生成 迭代器函数

js
function * fibonacci() { // 一个生成器函数
    let [prev, curr] = [0, 1];
    for (;;) { // while (true) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}
// 调用生成 迭代器函数 
for (let n of fibonacci()) {
     console.log(n);
    // 当n大于1000时跳出循环
    if (n >= 1000)
        break;
}

4.2、生成器不应该重用

js
// 此处 gen是一个固定的迭代器
var gen = (function *(){
    yield 1;
    yield 2;
    yield 3;
})();
for (let o of gen) {
    console.log(o);
    break;//关闭生成器
}
//生成器不应该重用,以下没有意义!
for (let o of gen) {
    console.log(o);
}