简体   繁体   中英

jQuery - Iterate over Objects with numeric keys

I have an Object:

var myObj = { 5: "foo", 25: "bar" };

Now i want to walk through the object like this:

$.each(myObj, function(key, value) {
    console.log(value); 
});

The problem is, that jQuery walks 26 times through the array while value will be "undefined" in 24 cases (i debugged it - thats fact). So it walks through the object 5 times before it reaches the fifth value (which is the first one).

I dont want to convert the object to an array since i want to store the data back into the stack after handling the data.

Is this a jQuery-Bug, a bug of mine or how to solve this?

Additional Info:

Here's a screenshot of my Chrome's DevTools shows the object at runtime.

sT.data.tasks contains the same content as splitTicket - just needed to show splitTicket because sT.data.tasks is lost inside the $.each-Scope. (Maybe that indicates the problem?) - Another thing to note is the "length" of the object with key "2517" - Is that a Google-Chrome Bug, a javascript Bug or just correct?

-> Note that at the current breakpoint tkey is 0 (int) and tval is undefined (undefined) and since this code wont produce any Errors, it walks through it 2517 times (did not count^^)

DevTools输出

It's not a bug at all. It looks like jQuery is just treating this object as an array and iterating over it in the normal way, starting from 0 and going to the largest key.

A for..in loop loops over the properties in the object.

Using the following only goes through 2 times:

for(key in myObj) {
    console.log(myObj[key]); 
};

Your example looks just fine to me:

var myObj = { 5: "foo", 25: "bar" };
$.each(myObj, function(key, value) {
    console.log(value); 
});
foo
bar

Looking at the jQuery source for $.each it appears to use for..in if your object isn't "arraylike".

I'd hypothesise that isArraylike returns true for your 'real' code (it's false for myObj)

jQuery $.each:

for ( i in obj ) {
    value = callback.call( obj[ i ], i, obj[ i ] );

    if ( value === false ) { break; }
}

jQuery isArraylike :

function isArraylike(obj) {
    var length = obj.length,
        type = jQuery.type(obj);

    if (jQuery.isWindow(obj)) {
        return false;
    }

    if (obj.nodeType === 1 && length) {
        return true;
    }

    return type === "array" || type !== "function" && (length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj);
}

try this,

var myObj = { 5: "foo", 25: "bar" };
var i=0;
Object.keys( myObj ).forEach(function ( name, index ) {
    var value = myObj[name];
    console.log(++i);
    console.log(name); // the property name
    console.log(value); // the value of that property
    console.log(index); // the counter
});

live DEMO

your code iterate two time at my side.but also you can try using this example.

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