5

I'm pretty new to javascript and I'm trying to iterate over a dictionaries key/values. (And yes, I read a few posts here, but didn't find the answere for.)

So this is my dictionary:

showhidedict = {
    0: ["a"],
    1: [],
    2: ["a", "b"],
    3: []
};

this is my iterating:

for (var value in showhidedict)
    $("#" + showhidedict[value]).hide();

resharper suggests me to add the hasOwnProperty-check into the loop:

if (showhidedict.hasOwnProperty(value))

But why?

the hasOwnProperty-check checks, whether an object has an attribute (here, whether the dictionary contains the key), right? But do I really need the check? Since I iterate over the keys, I know all keys must exist. Are there other points why I should add the check?

Matthias Burger
  • 5,549
  • 7
  • 49
  • 94
  • 1
    Objects inherit properties from other objects, i.e. `obj["foo"]` can return a value (and `"foo" in obj` will be true) even if `obj.hasOwnProperty("foo")` is false. – melpomene Aug 31 '16 at 06:59
  • What Resharper doing is **sugesting** you to make sure your data structure is valid. So, when you take some element from the object, you've not thrown. – Fadhly Permata Aug 31 '16 at 06:59
  • Your form of the `hasOwnProperty` check is wrong. It should be `if (Object.prototype.hasOwnProperty.call(showhidedict, value))`; otherwise the code will crash if one of the data properties in `showhidedict` is called `hasOwnProperty`. – melpomene Aug 31 '16 at 07:01
  • @melpomene okay, but that's what resharper is suggesting me – Matthias Burger Aug 31 '16 at 07:02
  • @MatthiasBurger In JavaScript objects **are** dictionaries. – 4castle Aug 31 '16 at 07:03
  • @4castle, sorry, now I seen... – Matthias Burger Aug 31 '16 at 07:03
  • 1
    The MDN documentation for [`hasOwnProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) is also helpful. – 4castle Aug 31 '16 at 07:06

2 Answers2

3

It is usually recommended to always use hasOwnProperty because indicates whether the object has the specified property on the object itself and avoiding lookup in its prototype chain.

Generally you should never assuming about the environment the code is running on or when your object is created by a different library, or whether the prototype have been extended so hasOwnProperty make your code "safer".

More information on prototype chain.

Reference to Object.prototype.hasOwnProperty().

GibboK
  • 71,848
  • 143
  • 435
  • 658
  • Please add a comment when down-voting so I can improve my answer. – GibboK Aug 31 '16 at 07:07
  • 1
    You should include more detail as to what a use case would be for this, since they are probably unfamiliar with extending the prototype if they are asking this question. Your answer makes sense to someone who already understands the concept, but is not helpful for teaching someone unfamiliar. – 4castle Aug 31 '16 at 07:09
  • @4castle Thanks for your comment, yes good idea, I had included some resources pointing out how js prototype works. +1 for your suggestion. – GibboK Aug 31 '16 at 07:15
  • Now I got it. I think the time will come, when I love JS. For now, I hate it :D – Matthias Burger Aug 31 '16 at 07:20
  • @MatthiasBurger I am glad my answer help you out. Whenever you need some clarifications on JS, the SO community is always ready to help :) – GibboK Aug 31 '16 at 07:22
1

If you use the in keyword to iterate, you are iterating object properties, the keys returned are strings, not numbers. In this context of iterating properties, it's prudent to always check you're only iterating that object's own properties, not whatever garbage lies up the prototype chain.

For iterating an Arraylike, the recommended iteration is probably still using a regular for loop with incrementing index. This index will be a number, it will rely on the length property that Arraylikes have. It will not need to check hasOwnProperty.

That being said, I don't think the code you wrote is wrong, but especially in team environments or using external APIs, it's probably prudent to use one of the above two methods. Resharper is all about being prudent with your code.

Simon Meskens
  • 928
  • 1
  • 6
  • 12
  • so if I work with an external object (another API, not mine), I should use it? – Matthias Burger Aug 31 '16 at 07:11
  • @MatthiasBurger definitely, if your object is created by another API you should not make any assumptions and make your code safer using hasOwnProperty as suggested by resharper. I have provided you a link with some additional resources on my answer, I hope you can find them useful. If you have any question, please let us know. Thanks! – GibboK Aug 31 '16 at 07:14