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