简体   繁体   中英

Is it possible to iterate over a js object's properties without using for in loop?

I'm trying to do something like this:

var myObject={'key1':value1, 'key2': value2, /*etc*/}; // big object created by an ajax call
var key=myObject.getFirstKey(); // something that does this. Maybe an immediately breaking for in loop.

function handleOne()
{
   var obj=myObject[key];
   // do something...
   key=myObject.getNextKey(); // something that does this.
   if (key===null) clearInterval(interval);
}

var interval=setInterval(handleOne,1000);

Afaik the only way to iterate over a js object is the for..in loop. Every time I tried to do something like this I needed to place all properties into an array.

I'm just wondering is it possible to get the next key from the previous one without messing with an array?

(This script is part of a graeasemonkey userscript so I don't mind if the solution is Firefox only.)

Not afaik. Apart from when using for..in loops, associative arrays don't have an intrinsic order. If you want it ordered, you might want to first take your associative array and map it to a normal indexed array such as this

var myMappedArray = [ { key = "Key1", value = value1 }, { key = "Key2", value = value2 }, ... ];

Then it's just a case of storing the current index into this array.

I see the reason that you cannot use for.. in loop is the setInterval call which makes your logic async and for.. in should only be executed synchronously

It is possible to get all keys associated with an object using Object.keys standard method (not supported in IE6-8), and then iterate with for statement:

var keys = Object.keys(myObject),
    i = 0;
function go() {
    var value = myObject[keys[i]];
    // handle value
    i++;
    if (i < keys.length) {
        setTimeout(go, 200);
    }
}
go();

and for IE6-8, just define keys function yourself:

!Object.keys && Object.keys = function(o) {
    var keys = [];
    for (var key in o) {
        keys.push(key);
    }
    return keys;
}

You could build the array at the outset and then wrap it in a function to peel off one element at a time. Something sort of like this perhaps:

function build_iterator(obj) {
    var keys = [ ];
    for(var k in obj)
        if(obj.hasOwnProperty(k))
            keys.push(k);
    return function() {
        return keys.pop();
    };
}

var get_next_key = build_iterator(my_object);

var interval = setInterval(handle_one, 1000);

function handle_one() {
    var key = get_next_key();
    if(key === null) {
        clearInterval(interval);
        return;
    }
    var obj = my_object[key];
    // Do something fantastic.
}

You can iterate over all properties in a JS Object using a loop like this:

for(var propertyName in myObject) {
   myObject[propertyName];
}

You will need to the looping AFAIK to get your first key out. So yes you'll need to do that and immediately break out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM