I've only delved into really writing JS for the last couple of weeks, but a number of tutorials basically said that objects are dictionaries and vice versa, you just got some nice syntax and you can plug function in as values.
If that was an abuse, what are JavaScript objects supposed to be? What's the difference between them and a dictionary?
It's only an abuse because JavaScript has no distinction between the notion of an object's "meta" properties, and its dictionary-like keys and values. So you'll get along just fine, until someone tries to write this:
Another problem with objects-as-dictionaries is that the keys must be strings. If you use a different type as a key, it is implicitly converted to a string, which can lead to some surprising problems for programmers who don't expect it.
Maps/Set/WeakMap properly support arbitrary objects as keys.
Again, this is something that is simple to learn and understand. And you would learn this in a beginner tutorial. Why go through trouble to change it and complicate the language even further? I undeerstand weakmap may have some real advantage as far as GC, at least.
Again, this is something that is simple to learn and understand. And you would learn this in a beginner tutorial. Why go through trouble to change it and complicate the language even further?
For one simple to understand != intuitive or easy to use. Chess rules are easy to understand too, you can learn all of them in an hour, but try to play the game with any quality. So this being simple to understand does not mean its simple to code around and debug.
You are also misguided in that this addition "complicates the language". It's not like adding generics or monads or some crazy new feature. It's one of the most fundamental datatypes, implemented properly for the first time.
So, instead of saying Object foo; foo.x = "a"; when you need a dict, and having to guard against all consequences, you get to use Map foo; foo.x = "a"; and there is nothing you have to think about anymore.
Byt anyone with even a basic tutorial understanding of the language wouldn't do that. Is it really necessary to try and make it absolutely impossible to get unexpected results? The downside is even more complexity and uncertainty. Now you have to know the old way, the new way, and the idiosynchracies of both.
But even if you use an arbitrary object....if it comes from a user supplied value you are going to have to validate it somehow.
It would be great if the post included good examples of how these things are going to produce better code. Maybe my imagination or experience is just insufficient to see the great win here.
Validated or not there are still many cases where this is a valid key and thus completely breaks the object. For example, this might be a login name, most people would consider it unreasonable to not allow js keywords as logins. For a simpler example, imagine a dictionary of syntax highlighted words for js ;)
There are workarounds of course, but the ironic result is that when you want to use a js object as an actual hash/dictionary (something we are repeatedly told js is great at), your code devolves into a defensive programming mess, requiring constructions like Object.prototype.hasOwnProperty.apply, etc.
then nothing can ever go wrong. This does have an annoyance around the leading underscores. But you can get around that by adding simple accessor methods. And now you have a real dictionary.
But native dictionaries have the ability to store complex objects as keys. This is kind of nice. However they are likely to create traps like making these 2 different:
Good point. I shouldn't have tossed that off of the top of my head, particularly since I'm not a JavaScript programmer. But the principle is right, you just need a different starting key than "_" to avoid conflict. Something like, "dict_" should work. And hide the details behind accessors. So if that breaks in a future version of JavaScript, it is easy to change it again.
Yes, let's add some arbitrary personal convention you have to follow and keep track of, because it's so much easy than a proper Map type...
But you can get around that by adding simple accessor methods. And now you have a real dictionary.
You still don't have a real dictionary, keys are only strings for example. You just have another lame-ass implementation of a dict in JS that avoids some edge cases and still falls prey to others.
However they are likely to create traps like making these 2 different: my_dict[5], my_dict['5']
Those two are different, but JavaScript does not encourage clarity about when you'll have one versus the other, thereby leading to traps for unwary beginners.
I just tested and it looks like it works in SquirrelFish/Nitro and SpiderMonkey as well. Cool trick — I didn't know about that.
But I don't think it quite solves the problem jashkenas is talking about, which is that JavaScript automatically calls certain properties of your object behind the scenes in many situations, so you aren't completely free to use any key you want. You might be able to use a no-proto object like this as the internal datastore for a map, but by itself an object with arbitrarily assigned keys would cause a lot of problems unless you were very careful with it.
If that was an abuse, what are JavaScript objects supposed to be? What's the difference between them and a dictionary?