Javascript 1.7以降、これを可能にする イテレータ オブジェクトがあります。
var a={a:1,b:2,c:3};
var it=Iterator(a);
function iterate(){
try {
console.log(it.next());
setTimeout(iterate,1000);
}catch (err if err instanceof StopIteration) {
console.log("End of record.\n");
} catch (err) {
console.log("Unknown error: " + err.description + "\n");
}
}
iterate();
node.jsにこのようなものはありますか?
今私は使っています:
function Iterator(o){
/*var k=[];
for(var i in o){
k.Push(i);
}*/
var k=Object.keys(o);
return {
next:function(){
return k.shift();
}
};
}
しかし、それはすべてのオブジェクトキーをk
に格納することによって多くのオーバーヘッドを生み出します。
あなたが欲しいのは、オブジェクトまたは配列に対する遅延反復です。これはES5では不可能です(したがって、node.jsでは不可能)。私たちは結局これを手に入れるでしょう。
唯一の解決策は、イテレータ(そしておそらくジェネレータ)を実装するためにV8を拡張するノードモジュールを見つけることです。実装が見つかりませんでした。 spidermonkeyのソースコードを見て、V8の拡張機能としてC++で書いてみてください。
あなたは以下を試すことができます、しかしそれはまたメモリにすべてのキーをロードします
Object.keys(o).forEach(function(key) {
var val = o[key];
logic();
});
しかしObject.keys
はネイティブなメソッドなので、より良い最適化が可能かもしれません。
ご覧のとおり、Object.keysはかなり高速です。実際のメモリストレージが最適かどうかは別の問題です。
var async = {};
async.forEach = function(o, cb) {
var counter = 0,
keys = Object.keys(o),
len = keys.length;
var next = function() {
if (counter < len) cb(o[keys[counter++]], next);
};
next();
};
async.forEach(obj, function(val, next) {
// do things
setTimeout(next, 100);
});
this
キーワードとして使用するオブジェクトを指定する .forEach()
関数に2番目の引数を渡すこともできます。
// myOjbect is the object you want to iterate.
// Notice the second argument (secondArg) we passed to .forEach.
Object.keys(myObject).forEach(function(element, key, _array) {
// element is the name of the key.
// key is just a numerical value for the array
// _array is the array of all the keys
// this keyword = secondArg
this.foo;
this.bar();
}, secondArg);
Node.jsは初めてです(約2週間)が、オブジェクトの内容をコンソールに再帰的に報告するモジュールを作成しました。それはすべてをリストするか、または特定の項目を検索し、必要ならば与えられた深さでドリルダウンします。
おそらくあなたはあなたのニーズに合うようにこれをカスタマイズすることができます。複雑にしないでおく!なぜ複雑なのか….
'use strict';
//console.log("START: AFutils");
// Recusive console output report of an Object
// Use this as AFutils.reportObject(req, "", 1, 3); // To list all items in req object by 3 levels
// Use this as AFutils.reportObject(req, "headers", 1, 10); // To find "headers" item and then list by 10 levels
// yes, I'm OLD School! I like to see the scope start AND end!!! :-P
exports.reportObject = function(obj, key, level, deep)
{
if (!obj)
{
return;
}
var nextLevel = level + 1;
var keys, typer, prop;
if(key != "")
{ // requested field
keys = key.split(']').join('').split('[');
}
else
{ // do for all
keys = Object.keys(obj);
}
var len = keys.length;
var add = "";
for(var j = 1; j < level; j++)
{
// I would normally do {add = add.substr(0, level)} of a precreated multi-tab [add] string here, but Sublime keeps replacing with spaces, even with the ["translate_tabs_to_spaces": false] setting!!! (angry)
add += "\t";
}
for (var i = 0; i < len; i++)
{
prop = obj[keys[i]];
if(!prop)
{
// Don't show / waste of space in console window...
//console.log(add + level + ": UNDEFINED [" + keys[i] + "]");
}
else
{
typer = typeof(prop);
if(typer == "function")
{
// Don't bother showing fundtion code...
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
}
else
if(typer == "object")
{
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
if(nextLevel <= deep)
{
// drop the key search mechanism if first level item has been found...
this.reportObject(prop, "", nextLevel, deep); // Recurse into
}
}
else
{
// Basic report
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "} = " + prop + ".");
}
}
}
return ;
};
//console.log("END: AFutils");
キー/値の単純な反復のために、 nderscorejs のようなライブラリーが友達になることがあります。
const _ = require('underscore');
_.each(a, function (value, key) {
// handle
});
参考のために
彼のコードを調整してください。
Object.prototype.each = function(iterateFunc) {
var counter = 0,
keys = Object.keys(this),
currentKey,
len = keys.length;
var that = this;
var next = function() {
if (counter < len) {
currentKey = keys[counter++];
iterateFunc(currentKey, that[currentKey]);
next();
} else {
that = counter = keys = currentKey = len = next = undefined;
}
};
next();
};
({ property1: 'sdsfs', property2: 'chat' }).each(function(key, val) {
// do things
console.log(key);
});