-1

I have inherited a deminified codebase as a personal project from the web archive.

There are many of these:

for (var keyCodeName in keyCodeByName) {
   // something happens
}

Is there a modern equivalent to this type of for loop which means the same thing? I get lost in "enumerable properties" when I try to research it.

user1059939
  • 1,613
  • 2
  • 20
  • 37
  • 1
    `for ... of` loop? – Phix Dec 23 '20 at 23:44
  • 4
    Does this answer your question? [How do I loop through or enumerate a JavaScript object?](https://stackoverflow.com/questions/684672/how-do-i-loop-through-or-enumerate-a-javascript-object) – vpzomtrrfrt Dec 23 '20 at 23:45
  • 3
    it can depend on what `something happens` does – Jaromanda X Dec 23 '20 at 23:46
  • @Phix nope! for... in, I haven't used in it 10 years so it's weird to me to understand, but it is all over the codebase. – user1059939 Dec 23 '20 at 23:46
  • 3
    What is wrong with the `for...in` loop? Why does it need to be replaced? – Ivar Dec 23 '20 at 23:48
  • @Ivar never seen it in my life in any open source code or my own understanding of the language. TypeScript starts to moan at me in `strict` mode but after many days I don't get it. The same way there is for(itr) or map... I want to ditch it for something less lame. – user1059939 Dec 23 '20 at 23:49
  • @JaromandaX in what context? – user1059939 Dec 23 '20 at 23:51
  • 2
    There are some issues with `for...in` if not used properly, [one article here](http://adripofjavascript.com/blog/drips/the-problem-with-for-in-and-javascript-arrays.html). – Phix Dec 23 '20 at 23:51
  • 2
    to iterate over keys a equivalent would be `Object.keys(myObj).forEach()`, though at first glance I don't see why would change it... – buzatto Dec 23 '20 at 23:52
  • But @buzatto is that a true statement? Is it literally the equivalent? I understand that. – user1059939 Dec 23 '20 at 23:53
  • @Phix thank you, I will check this out. Can someone tell me what "enumerable" means? All objects have properties. Why are some "enumerable" ? – user1059939 Dec 23 '20 at 23:54
  • @user1059939 I think Phix was suggesting you use a `for ... of ` loop. – Brad Dec 23 '20 at 23:56
  • @Brad but is `for...of` literally `for...in`? Even `for...of` I can understand. – user1059939 Dec 23 '20 at 23:57
  • `for..in` is probably the fastest loop over any other than `for..of`, `forEach`, `Object.keys` and `Object.entries` so why change it? – Endless Dec 23 '20 at 23:58
  • 1
    @user1059939 No, it's different, but you haven't explained what it is you want to change and why. – Brad Dec 23 '20 at 23:59
  • @Brad thank you, in that case, as also others have stated, it depends on the usage... So for ever `for...in` context matters and that sucks.... – user1059939 Dec 24 '20 at 00:00
  • [enumerable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) – Barmar Dec 24 '20 at 00:11
  • 1
    what context @user1059939? In the context of what the code is doing - I can't address every single possible scenario - the point is, there are many "tools" to iterate "something" in javascript - the best "tool" is the correct "tool" – Jaromanda X Dec 24 '20 at 00:20
  • for...in is still considered modern. It's not obsolete and there is no reason not to use it. – PHP Guru Dec 24 '20 at 02:12

1 Answers1

2

The closest equivalent is looping over Object.keys() with forEach():

Object.keys(keyCodeByName).forEach(keyCodeName => {
    // something happens
});

This is actually roughly equivalent to the following loop:

for (let keyCodeName in keyCodeByName) {
    if (keyCodeByName.hasOwnProperty(keyCodeName)) {
        // something happens
    }
}

because Object.keys() only returns own properties, while for-in will process inherited properties as well.

Many programmers forget to do the hasOwnProperty() check, and in most cases it's innocuous because none of the inherited properties are enumerable. So if the code you're trying to convert doesn't have the check, it's more likely that they didn't realize they needed it, not that they really want to process inherited properties. So using Object.keys() is likely to be closer to the intended behavior.

See When do I need to use hasOwnProperty()?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • This is exactly the bare bones explaination that I was after. Thank you for taking the time to write it Barmar. In TypeScript this check is flagged in strict mode and was the missing key I needed. – user1059939 Dec 24 '20 at 00:47
  • object.hasOwnProperty() checks are not needed anymore due to the very point you made about inherited properties being non-enenumerable. If you are adding inherited properties that are enumerable then you're doing something wrong or you're using an old browser that doesn't allow you to change enumerablility. The only reason to still do the check is to support old browsers. There is nothing wrong with using for...in. It's more efficient than using Object.keys() with .forEach() – PHP Guru Dec 24 '20 at 01:56
  • @PHPGuru True, and the question I linked to has a link to a web site explaining why it's not necessary. But it also presumes that people will extend `Object.prototype` in the correct way (with `defineProperty` and `enumerable: false`), which is not something you can always count on. – Barmar Dec 24 '20 at 06:05