开发者

Iterating over javascript object and valueOf toString methods

var x = {
    article: "bla bla bla ",
    journal: "le monde ",
    magazine: "playboy"
};

for (var i in x) { 
    alert(i + " "+ x[i]);
}

Every JS object has a valueOf and a toString metho开发者_开发问答d. Why can't I see them when I iterate over the properties of the x object?


They are not enumerable properties. Try Object.getOwnPropertyNames. Only works in some browsers:

This DOESNT check proto though, so you need to do something very complicated:

var x, y, z, getAllKeys;
getAllKeys = function (obj,ar) {
    ar = ar || [new Array];
    ar[0] = ar[0].concat(Object.getOwnPropertyNames(obj));
    if (obj !== Function.prototype && Object.getPrototypeOf(obj)) {
        getAllKeys(Object.getPrototypeOf(obj),ar);
    }
    return ar[0];
}
console.log (getAllKeys(new Array));
for (x in y = getAllKeys(z = new Array)) {
    var key = y[x];
    var value = z[y[x]];
}

Blame JavaScript for being ridiculous and looking like assembly, maybe jASM would be a better name? (joke)


The engine specifically hides these methods from enumeration.

The purpose of this is to allow to iterate over Object properties without being annoyed by the object's prototypal properties. This way you can iterate over Array indices, use Objects as hash tables and iterate over its properties.

This can however be easily broken. For example if you use a custom method in Object.property, it will suddenly appear during the enumeration of all objects' properties:

var obj = { foo: 0 };

Object.prototype.bar = 1;

// prints 'foo' and 'bar'
for (var k in obj) {
    console.log(k);
}

This is makes it dangerous to extend Object.prototype.

You can test if a property comes from the object itself or it's prototype by using the Object.hasOwnProperty method:

// prints 'foo'
for (var k in obj) {
    if (!obj.hasOwnProperty(a)) continue;
    console.log(k);
}

Alternatively, you could use Object.defineProperty do define non-enumerable properties, if you don't care of old browsers:

Object.defineProperty(Object.prototype, 'bar', {value: 1, enumerable: false});

// prints 'foo'
for (var k in obj) {
    console.log(k);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜