If not for-in then what?

# John J Barton (13 years ago)

In another thread Allen says:

we infer from array behavior that for-in was intended to iterate over the data elements of an object and not the behavioral elements (eg methods).

Similar comments have been implied around the discussion of enumerable properties. I personally have never seen any JS code that had this assumption. On the contrary, before Object.keys(), for-in was widely used as a half-baked meta-programming iterator.

If for-in is not intended to iterate all properties of an object then what is?

jjb

# Axel Rauschmayer (13 years ago)

On Mar 28, 2012, at 17:06 , John J Barton wrote:

In another thread Allen says:

we infer from array behavior that for-in was intended to iterate over the data elements of an object and not the behavioral elements (eg methods).

Similar comments have been implied around the discussion of enumerable properties. I personally have never seen any JS code that had this assumption. On the contrary, before Object.keys(), for-in was widely used as a half-baked meta-programming iterator.

If for-in is not intended to iterate all properties of an object then what is?

Object.getOwnPropertyNames() together with a hand-written traversal of the prototype chain.

# Allen Wirfs-Brock (13 years ago)

On Mar 28, 2012, at 8:06 AM, John J Barton wrote:

In another thread Allen says:

we infer from array behavior that for-in was intended to iterate over the data elements of an object and not the behavioral elements (eg methods).

Similar comments have been implied around the discussion of enumerable properties. I personally have never seen any JS code that had this assumption. On the contrary, before Object.keys(), for-in was widely used as a half-baked meta-programming iterator.

Prior to ES5, for-in was the closest approximation of "iterate all property of an object" that existed in the language. No doubt that the vast majority of JS code you have inspected was written assuming ES3 capabilities, so for-in was the best available solution. However, for-in does not enumerate all properties. In particular, the vast majority of properties defined in Chapter 15 of the specification are not enumerated by for-in.

If for-in is not intended to iterate all properties of an object then what is?

Object.getOwnPropertyNames and Object.getPrototypeOf are the meta-programming foundation provided by ES5 for actually enumerating over all properties.

Other than for meta-programming, what is an use case for enumerating all properties including methods?

# John J Barton (13 years ago)

On Wed, Mar 28, 2012 at 8:24 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

On Mar 28, 2012, at 8:06 AM, John J Barton wrote:

In another thread Allen says:

we infer from array behavior that for-in was intended to iterate over the data elements of an object and not the behavioral elements (eg methods).

Similar comments have been implied around the discussion of enumerable properties. I personally have never seen any JS code that had this assumption. On the contrary, before Object.keys(), for-in was widely used as a half-baked meta-programming iterator.

Prior to ES5, for-in was the closest approximation of "iterate all property of an object" that existed in the language. No doubt that the vast majority of JS code you have inspected was written assuming ES3 capabilities, so for-in was the best available solution. However, for-in does not enumerate all properties. In particular, the vast majority of properties defined in Chapter 15 of the specification are not enumerated by for-in.

If for-in is not intended to iterate all properties of an object then what is?

Object.getOwnPropertyNames and Object.getPrototypeOf are the meta-programming foundation provided by ES5 for actually enumerating over all properties.

But there are no operations for just methods or just non-methods correct?

Other than for meta-programming, what is an use case for enumerating all properties including methods?

My question was aimed at the design discussion that mention for-in. I should have tried:

What is the use case for 'for-in'? What is the purpose of a language feature that is so inconsistent that experts attempt to infer its design?

jjb

# Andrea Giammarchi (13 years ago)

I'd love to see this implemented natively ...

(function (Object) { var forEach = "forEach", ObjectPrototype = Object.prototype getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor ; forEach in ObjectPrototype || Object.defineProperty( ObjectPrototype, forEach, {value: function forEach(callback, context) { for (var self = this, props = getOwnPropertyNames(self), i = 0, length = props.length, key; i < length; ++i ) { callback.call( context, key = props[i], getOwnPropertyDescriptor(self, key), self ); } }} ); }(this.Object));

where an example would be

var o = {a:123}; o.forEach(function (key, descriptor, obj) { alert([ key, // "a" descriptor.value, // 123 obj == o, // true this == window // true ]); }, this);

consistent with Array.prototype.forEach API while a proper Object.prototype.forIn or just Object.forIn may look up until the prototype chain is complete ...

(function (Object) { var forIn = "forIn", ObjectPrototype = Object.prototype getPrototypeOf = Object.getPrototypeOf ; forIn in ObjectPrototype || Object.defineProperty( ObjectPrototype, forIn, {value: function forIn(callback, context) { var self = this; do { self.forEach(callback, context); } while (self = getPrototypeOf(self)); }} ); }(this.Object));

so that

var o1 = {a:123}; var result = []; o1.forIn(function (key, descriptor) { result.push(key, descriptor.value); }); alert(result);

my 2 cents

# Andrea Giammarchi (13 years ago)

actually, to be consistent with Array.prototype.forEach, descriptor should be the first argument ... apologies

# Allen Wirfs-Brock (13 years ago)

For ES5, we made the decision to keep new meta-programming APIs off of Object.prototype. I think it was a wise decision. Consistent with it, if we added something like this it would be on Object, not Object.prototype or more likely in ES6 in a built-in module.

However, you have nicely demonstrated that the existing reflection APIs are quite adequate for defining such a function. There isn't anything that requires additional primitive built-in support, so why does it need to be implemented natively?

One of the ES5 goals was empowerment of library writers. Why don't you write and evangelize your ideal JS meta-programming library. You don't need to wait for TC39 to standardize something and browser venders to implement it.

# Andrea Giammarchi (13 years ago)

Well, that forEach is shadowed by Array.prototype.forEach while forIn will scale with arrays too ... in ES5 many global prototype have been implemented over existing libraries indeed but what we all deal with on daily basis are mostly Objects and few methods there could be handy.

Regardless these considerations, I agree with your points ... I am always happy when I can do things and ES5 for this task is one again handy enough to obtain the desired logic.

it was just a suggestion, not a must have, and native was because it's most of the time much faster ;-)

br