Object.prototype.forIn

# Langdon (9 years ago)

My apologies if this has been discussed before (I have to imagine it has, but couldn't find anything).

Why isn't there a forIn method on Object natively?

Something that simply wraps this all-to-common code:

var key;

for (key in obj) { if (obj.hasOwnProperty(key) === true) { ... } }

Example: jsfiddle.net/langdonx/d4Lph13u

TIA, Langdon

# Logan Smyth (9 years ago)

You can already achieve this in ES5 with

Object.keys(obj).forEach(key => {

});

or in ES6 with

var key;
for (key of Object.keys(obj)){

}

And with the new proposal, you'll also have Object.values for values and Object.entries for key/value pairs: tc39/proposal

# Langdon (9 years ago)

Ah, thanks. I had forgotten about Object.keys, but even that still doesn't wrap things up as nicely as forIn.

Object.entries looks nice.

# Simon Blackwell (9 years ago)

Not sure of the rationale; however, it looks like Chrome now supports something similar natively:

twitter.com/malyw/status/704972953029623808?utm_source=javascriptweekly&utm_medium=email, twitter.com/malyw/status/704972953029623808?utm_source=javascriptweekly&utm_medium=email

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Langdon Sent: Friday, March 4, 2016 11:22 AM To: es-discuss at mozilla.org Subject: Object.prototype.forIn

My apologies if this has been discussed before (I have to imagine it has, but couldn't find anything).

Why isn't there a forIn method on Object natively?

Something that simply wraps this all-to-common code:

var key;

for (key in obj) {

if (obj.hasOwnProperty(key) === true) {

...

}

}

Example: jsfiddle.net/langdonx/d4Lph13u

TIA,

Langdon

# Andrea Giammarchi (9 years ago)

for (let key of Object.keys(obj)) { ... }

# Isiah Meadows (9 years ago)

Yeah, and those effectively nullify this, anyways.

# Langdon (9 years ago)

My gripe with Object.keys is that it requires a closure to use effectively.

Object.entries does look nice, but 2 arguments is more straightforward than a passing around a pair.

As well (and perhaps more importantly), temporarily building an array of arrays so we can forEach it, seems way less efficient than forIn is/would be.

# Simon Blackwell (9 years ago)

No doubt … which brings us right back to the rationale question!

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Langdon Sent: Friday, March 4, 2016 1:28 PM To: es-discuss at mozilla.org Subject: Re: Object.prototype.forIn

My gripe with Object.keys is that it requires a closure to use effectively.

Object.entries does look nice, but 2 arguments is more straightforward than a passing around a pair.

As well (and perhaps more importantly), temporarily building an array of arrays so we can forEach it, seems way less efficient than forIn is/would be.

On Fri, Mar 4, 2016 at 1:20 PM, Isiah Meadows <isiahmeadows at gmail.com <mailto:isiahmeadows at gmail.com> > wrote:

Yeah, and those effectively nullify this, anyways.

On Fri, Mar 4, 2016, 12:55 Simon Blackwell <syblackwell at anywhichway.com <mailto:syblackwell at anywhichway.com> > wrote:

Not sure of the rationale; however, it looks like Chrome now supports something similar natively:

twitter.com/malyw/status/704972953029623808?utm_source=javascriptweekly&utm_medium=email, twitter.com/malyw/status/704972953029623808?utm_source=javascriptweekly&utm_medium=email

From: es-discuss [mailto:es-discuss-bounces at mozilla.org <mailto:es-discuss-bounces at mozilla.org> ] On Behalf Of Langdon

Sent: Friday, March 4, 2016 11:22 AM To: es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>

Subject: Object.prototype.forIn

My apologies if this has been discussed before (I have to imagine it has, but couldn't find anything).

Why isn't there a forIn method on Object natively?

Something that simply wraps this all-to-common code:

var key;

for (key in obj) {

if (obj.hasOwnProperty(key) === true) {

...

}

}

Example: jsfiddle.net/langdonx/d4Lph13u

TIA,

Langdon

# Caitlin Potter (9 years ago)

Object.entries does look nice, but 2 arguments is more straightforward than a passing around a pair.

What’s the problem with for (let [key, value] of Object.entries(obj)) { …. }

As well (and perhaps more importantly), temporarily building an array of arrays so we can forEach it, seems way less efficient than forIn is/would be.

You might be surprised — If the pair never reaches geriatric status (old generation/tenured space, etc), it could be allocated and cleaned up relatively quickly.

# Langdon (9 years ago)

Ahhh, nothing. I never think about destructuring.

# Edwin Reynoso (9 years ago)

Sorry guys but this is very wrong, for in, loops through all properties even the ones inherited from all prototypes, while Object.keys() and Object.entries() do not. They are indeed very different

# Logan Smyth (9 years ago)

Edwin, the original example loop explicitly checks obj.hasOwnProperty(key), so properties in the prototype chain are not an issue here.

# Edwin Reynoso (9 years ago)

Okay that makes sense, but the Object.forIn confused me, then that'd be a bad name because then its not really looping like for

# Jordan Harband (9 years ago)

While I would like a function for this too, this is pretty trivial:

function* enumerate(obj) { for (var key in obj) { yield [key, obj[key]]; } }

for (const [key, value] of enumerate(obj) {
  doStuff(key, value);
}
# /#!/JoePea (9 years ago)

Nice use of generators! I'll save this one into my toolbox.

/#!/JoePea

# Bergi (9 years ago)

Langdon wrote:

Something that simply wraps this all-to-common code:

var key;

for (key in obj) { if (obj.hasOwnProperty(key) === true) { ... } }

Imo the problem is not that there is no wrapper method for this pattern, but that this code is all too common. It should rarely be needed, and is mostly wrong anyway.

The cases to consider are

  • You use obj as a dictionary. If you want to safeguard against inherited properties, you use obj = Object.create(null). Those objects don't even have a .hasOwnProperty method. And with ES6, a Map is a better solution anyway.

  • You are enumerating array keys. To safeguard against inherited properties from Array.prototype, you should not use hasOwnProperty but rather use the proper loop type that iterates indices instead.

  • You are processing JSON. JSON.parse'd objects inherit only from Object.prototype which does not have enumerable properties anyway.

  • You are processing (JSON/dictionary) objects and fear that someone added enumerable properties to Object.prototype. Well, that's their fault, not your loop's one. If the environment is broken, your code is as well; there's nothing you can - and need - to do against.

  • You are processing arbitrary objects with unknown prototype chains. To skip inherited properties in a for in loop, the only safe approach is to use if (Object.prototype.hasOwnProperty.call(obj, key)) or avoid the drama altogether via Object.keys/Object.getOwnProperty….

The last case is the only one where you'd really need hasOwnProperty. The proliferation of if (obj.hasOwnProperty(key)) needs to be stopped, it's cargo cult programming at best.

, Bergi

# Leo Balter (9 years ago)

I have a proposal I'm finally bringing to es-discuss.

leobalter/object-keysin-valuesin-entries-in (rationale, examples and steps included)

I've already talked to some TC39 members about it and I believe it fits right on this topic.

# Kevin Smith (9 years ago)
  1. How is a user supposed to intuit the difference between Object.keys and Object.keysIn? For a non-expert, it sounds like the same thing.
  2. With "keys", "entries", etc., we lead the user down the "safe" object-as-dict path. Does adding these methods undo some of that leading? What are the compelling use-cases for proto-chain-as-dict?
# Caitlin Potter (9 years ago)

What exactly is the use case for iterating over each key/value pair in the entire prototype chain? Just curious

# Leo Balter (9 years ago)
  1. How is a user supposed to intuit the difference between Object.keys

and Object.keysIn? For a non-expert, it sounds like the same thing.

I've had funny conversations trying to find the best name for these methods. With _.keysIn, valuesIn and now entriesIn are already present on Lodash, with a similar behavior, I assume it's easier to conciliate them from it.

I tried other names, like enumerateKeys, allKeys, etc, I ended up convinced the current proposal has the better names we can use.

  1. With "keys", "entries", etc., we lead the user down the "safe"

object-as-dict path. Does adding these methods undo some of that leading? What are the compelling use-cases for proto-chain-as-dict?

Having these methods following the same initial keyword (keys to keysIn, values to valuesIn) makes it a bit easier to tell the extended name method catches the extended properties.

What are the compelling use-cases for proto-chain-as-dict?

As an example, the current Lodash implementation uses _.keysIn extensively on object cloning and mapping utilities, including variations of assign functions like _.assign, _.assignIn and _.functionsIn. This is useful on functional and immutable paradigms. Some of these methods also use the value pairs. The previous Reflect.enumerate supported these methods until it got removed along the [[Enumerate]] internal.