Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JavaScript's for in loop iterate over methods?

In an article on yuiblog Douglas Crockford says that the for in statement will iterate over the methods of an object. Why does the following code not produce ["a", "b", "c", "d", "toString"]? Aren't .toString() and other methods members of my_obj?

Object.prototype.toString = function(){return 'abc'}
Object.prototype.d = 4;

my_obj = {
    'a':1,
    'b':2,
    'c':3
}

a = []
for (var key in my_obj) {
    a.push(key)
}

console.log(a) // prints ["a", "b", "c", "d"]
like image 800
hekevintran Avatar asked Mar 30 '10 01:03

hekevintran


2 Answers

All user defined properties are enumerable, including the properties inherited from prototype. The built-in native properties are not. toString() is one of them. See here https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Statements/For...in

Edit: My interpretation of "However, the loop will iterate over all user-defined properties (including any which overwrite built-in properties)" is that the properties that are overwritten directly in the object become enumerable. Not the overwrite in the prototype itself. That means:

var my_obj = {a: 1, b: 2, c: 3};
my_obj.toString = function() {return 'abc';};

a = []
for (var key in my_obj) {
    a.push(key)
}

console.log(a) // prints ["a", "b", "c", "toString"]
like image 187
Chetan S Avatar answered Sep 22 '22 00:09

Chetan S


for..in iterates over user-defined properties. If you change your code to:

Object.prototype.foo = function() { return 'abc'; };

Then

console.log(a);

Will output:

["a", "b", "c", "foo", "d"]

As Chetan Sastry pointed pointed out, toString is treated differently since it is a built-in, native property.

like image 38
Justin Johnson Avatar answered Sep 24 '22 00:09

Justin Johnson