简体   繁体   中英

Finding object keys in Javascript

I'm working on an ExtJS webapp and was looking for a way to list all of an object's own property names. Googling around, I quickly found some reference code on this blog . Now, when using this keys() method, I find some strange behavior when enumerating the property names of an object of objects. Example code:

keys = function(obj) {
    if (typeof obj != "object" && typeof obj != "function" || obj == null) {
        throw TypeError("Object.keys called on non-object");
    }
    var keys = [];
    for (var p in obj) 
        obj.hasOwnProperty(p) && keys.push(p);
    return keys;
};

var test = {}
test["nr1"] = {testid: 1, teststr: "one"};
test["nr2"] = {testid: 2, teststr: "two"};
test["nr3"] = {testid: 3, teststr: "three"};
for (var i in keys(test)) {
    console.log(i);
}

When running this code, the console outputs:

0
1
2
remove()

So, on top of the expected 3 property names, it also lists a "remove()" function. This is clearly related to ExtJS, because the enumeration works as expected on a blank, non-ExtJS loading page.

Can anyone explain me what exactly ExtJS is doing here? Is there a better way to enumerate object-own property names?

Thanks a bunch, wwwald

Try to check hasOwnProperty to only list properties of the array itself, not its prototype.

for (var i in keys(test)) {
    if(keys(test).hasOwnProperty(i)){
      console.log(i);
    }
}

Yes, as @Thai said, not use for..in, as any array is a object and potentially could have different additions in different frameworks.

keys = function(obj) {
    if (typeof obj != "object" && typeof obj != "function" || obj == null) {
        throw TypeError("Object.keys called on non-object");
    }
    var keys = [];
    for (var p in obj) 
        obj.hasOwnProperty(p) && keys.push(p);
    return keys;
};

var test = {}
test["nr1"] = {testid: 1, teststr: "one"};
test["nr2"] = {testid: 2, teststr: "two"};
test["nr3"] = {testid: 3, teststr: "three"};
document.writeln('<pre>');
document.writeln('Current method');
for (var key in keys(test)) {
    document.writeln(key);
}


document.writeln('Better method1');
for (var arr=keys(test), i = 0, iMax = arr.length; i < iMax; i++) {
    document.writeln(arr[i]);
}

document.writeln('Better method2');
Ext.each(keys(test), function(key) {
   document.writeln(key); 
});
document.writeln('</pre>');

keys(test) returns an array, so you are expected to use the classic for-init-condition-next loopm and not the for-in loop.

(function(arr) {
    for (var i = 0; i < arr.length; i ++) {
        console.log(i);
    }
})(keys(test));

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