JavaScript迭代器类

JavaScript迭代器类,javascript,iterator,Javascript,Iterator,您知道一个JavaScript库,它为集合(无论是数组还是一些抽象可枚举的集合)实现了一个通用迭代器类,并具有一整套功能,如或 编辑:Enumerable#每个都不是迭代器类。我正在寻找一个迭代器,它可以让我们编写如下内容: var iterator = new Iterator(myCollection); for (var element = iterator.next(); iterator.hasNext(); element = iterator.next()) { // it

您知道一个JavaScript库,它为集合(无论是数组还是一些抽象可枚举的集合)实现了一个通用迭代器类,并具有一整套功能,如或

编辑:
Enumerable#每个
都不是迭代器类。我正在寻找一个迭代器,它可以让我们编写如下内容:

var iterator = new Iterator(myCollection);
for (var element = iterator.next(); iterator.hasNext(); element = iterator.next()) {
    // iterator 
}
编辑:mamoo让我们想起了中的迭代器实现。现在的目标是在JavaScript1.5(ECMA4)中找到这个迭代器函数的实现

Edit2:当库(和ECMA5)提供
每个方法时,为什么要使用迭代器?首先,因为
each
通常会弄乱
this
,因为回调是
call
-ed(这就是
each
在原型中接受第二个参数的原因)。然后,因为人们更熟悉(;;)
构造的
,而不是
.each(callback)
构造(至少在我的字段中)。最后,因为迭代器可以在普通对象上进行迭代(请参见JavaScript 1.7)

Edit3:我接受了npup的anwser,但这是我的尝试:

function Iterator(o, keysOnly) {
    if (!(this instanceof arguments.callee))
      return new arguments.callee(o, keysOnly);
    var index = 0, keys = [];
    if (!o || typeof o != "object") return;
    if ('splice' in o && 'join' in o) {
        while(keys.length < o.length) keys.push(keys.length);
    } else {
        for (p in o) if (o.hasOwnProperty(p)) keys.push(p);
    }
    this.next = function next() {
        if (index < keys.length) {
            var key = keys[index++];
            return keysOnly ? key : [key, o[key]];
        } else throw { name: "StopIteration" };
    };
    this.hasNext = function hasNext() {
        return index < keys.length;
    };
}



var lang = { name: 'JavaScript', birthYear: 1995 };  
var it = Iterator(lang);
while (it.hasNext()) {
    alert(it.next());
}
//alert(it.next()); // A StopIteration exception is thrown  


var langs = ['JavaScript', 'Python', 'C++'];  
var it = Iterator(langs);
while (it.hasNext()) {
    alert(it.next());
}
//alert(it.next()); // A StopIteration exception is thrown  
函数迭代器(o,仅限键){
if(!(此实例为arguments.callee))
返回新参数。被调用方(o,仅限键);
var指数=0,键=[];
如果(!o | | typeof o!=“object”)返回;
if(o中的“拼接”和o中的“连接”){
while(keys.length
JQuery有each()方法:

但即使在其他库中,比如Moo或Dojo,也可能有类似的东西

Javascript 1.7实现了迭代器函数:

我在一些项目中使用了LINQ到Javascript


好的,可枚举模式不是一个真正的迭代器

这(下面)对你有用吗?它至少符合您给出的语义。像往常一样,这里和那里都需要权衡,而我在决定这一次时并不费劲:)。
也许你希望能够发送一两个数字,并以这种方式在一个范围内迭代。但这可能是一个开始(支持对哈希、数组和字符串进行迭代)

这是一个完整的演示页面,它自己运行并进行一些调试输出,但(可能)有趣的东西在

window.npup = (function() {
    [...]
})();
斑点

也许只有我一个人根本不懂,但在实际情况下,你会使用这样一个类似java的迭代器做什么呢

最好的 /npup


无标题
    window.log=(函数(outputreaid){ var myConsole=document.getElementById(outputAreaId); 函数createElem(颜色){ var elem=document.createElement('li'); elem.style.color=颜色; 返回元素; } 函数appendElem(elem){ 追加子实体(elem); } 函数调试(msg){ var elem=createElem('#888'); elem.innerHTML=msg; 附属物; } 函数错误(msg){ var elem=createElem('#f88'); elem.innerHTML=msg; 附属物; } 返回{ 调试:调试 ,error:error }; })(‘输出’); window.npup=(函数(){ //Crockford先生提议的阵列检查 函数isArray(候选){ 返回候选人&& 候选对象的类型===“对象”&& 候选类型。长度==='number'&& typeof candidate.splice===“函数”&& !(候选.属性可枚举('length'); } 功能滴度(收集){ //检查一些不合适的东西 返回(!collection | | typeof collection=='number'| | typeof collection=='boolean'); } 函数迭代器(集合){ if(typeof collection==='string'){collection=collection.split(“”);} 如果(dontIterate(collection)){throw new Error('哦,你这个讨厌的家伙,我不会重复('+collection+')!');} var arr=isArray(集合); var idx=0,top=0; var key=[],prop; if(arr){top=collection.length;} else{for(集合中的道具){keys.push(道具);} this.next=函数(){ 如果(!this.hasNext()){抛出新的错误('哦,你这个讨厌的家伙,我没有更多的元素');} var elem=arr?collection[idx]:{key:keys[idx],value:collection[keys[idx]}; ++idx; 返回元素; };
    this.hasNext=function(){return arr?idx我仍然是js.class的学习者。 虽然和Ruby很亲近,但对我有帮助

    MarkT

    这是我对ECMAScript 262第五版(又名Javascript)的尝试()

    守则:

    function Iterator(input,keys) {
      // Input:
      //  input : object|array
      //  keys   : array|undefined|boolean
      function my() {
        ++my.index;
        if (my.index >= my.keys.length) {
          my.index = my.keys.length -1;
          my.key = my.value = undefined;
          return false;
        }
        my.key = my.useIndex ? my.index : my.keys[my.index];
        my.value = my.input[my.key];
        return my.index < my.keys.length;
      }
      if (input === null || typeof input !== 'object') {
        throw new TypeError("'input' should be object|array");
      }
      if (
        !Array.isArray(keys)
        && (typeof keys !== 'undefined')
        && (typeof keys !== 'boolean')
        ) {
        throw new TypeError("'keys' should be array|boolean|undefined");
      }
      // Save a reference to the input object.
      my.input = input;
      if (Array.isArray(input)) {
        //If the input is an array, set 'useIndex' to true if 
        //the internal index should be used as a key.
        my.useIndex = !keys;
        //Either create and use a list of own properties,
        // or use the supplied keys
        // or at last resort use the input (since useIndex is true in that
        // case it is only used for the length)
        my.keys = keys===true ? Object.keys(input) : keys || input;
      } else {
        my.useIndex = false;
        my.keys = Array.isArray(keys) ? keys : Object.keys(input);
      }
      // Set index to before the first element.
      my.index = -1;
      return my;
    }
    

    因为还没有提到这一点,所以数组内置了高阶函数

    Map的工作原理类似于迭代器,它只能执行一次传递

    [1,2,3,4,5].map( function(input){ console.log(input); } );
    
    此代码将列表中的每个元素传递到一个函数中,在本例中是一个简单的打印机

    1
    2
    3
    4
    5
    

    自提出此问题以来,JavaScript添加了actual。一些内置类型,例如,和,现在有默认的迭代行为,但您可以通过包含一个
    next()
    函数将自己的添加到任何对象,该函数返回两个对象之一:

    {done:true}     /*or*/
    {done:false, value:SOMEVALUE}
    
    访问对象的一种方法
    function Person(firstname, lastname, domain) {
      this.firstname = firstname;
      this.lastname = lastname;
      this.domain = domain;
    }
    Person.prototype.type = 'Brillant';
    
    var list = [
      new Person('Paula','Bean','some.domain.name'),
      new Person('John','Doe','another.domain.name'),
      new Person('Johanna','Doe','yet.another.domain.name'),
    ];
    
    var a,b; 
    var data_array = ['A','B','C','D','E','F'];
    data_array[10]="Sparse";
    
    
    console.log('Iterate over own keys in an object, unknown order');
    a = Iterator(list[0]);
    while(a()) console.log("  ",a.key, a.value);
    
    console.log('Iterate over keys from anywhere, in specified order');
    a = Iterator(list[0], ['lastname','firstname','type']);
    while(a()) console.log("  ",a.key, a.value);
    
    console.log('Iterate over all values in an array');
    a = Iterator(list);
    while(a()) console.log(a.key, a.value.firstname, a.value.lastname);
    
    
    //Some abusing, that works for arrays (if the iterator.keys is modified
    //it can also be used for objects)
    console.log('Add more entries to the array, reusing the iterator...');
    list.push(new Person('Another','Name','m.nu'));
    while(a()) console.log(a.key, a.value.firstname, a.value.lastname);
    
    console.log('Reset index and print everything again...');
    a.index=-1; //Reset the index.
    while(a()) console.log(a.key, a.value.firstname, a.value.lastname);
    
    //With arrays, if setting 'keys' to true it will only print the
    //elements that has values (If the array has more own enumerable values
    //they too will be included)
    console.log('Print sparce arrays...');
    a = Iterator(data_array,true);
    while(a()) console.log(a.key, a.value);
    
    [1,2,3,4,5].map( function(input){ console.log(input); } );
    
    1
    2
    3
    4
    5
    
    {done:true}     /*or*/
    {done:false, value:SOMEVALUE}
    
    for ( var of object ) { }
    
    "use strict";
    
    function count ( i ) {
      let n = 0;
      let I = {};
      I[Symbol.iterator] = function() {
         return { next: function() { return (n > i) ? {done:true}
                                                    : {done:false, value:n++} } } };
      let s = "";
      let c = "";
      for ( let i of I ) {       /* use the iterator we defined above */
          s += c + i;
          c = ", "
      }
      return s;
    }
    
    
    let s = count(3);
    console.log(s);