5 ms·
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
by Lewisham 15y ago
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?
- jashkenas 15y agoIt'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: var dict = {}; dict["hasOwnProperty"] = true; dict["toString"] = "Bob"; dict["valueOf"] = 7; ... then you're in for a rough time.
- mbrubeck 15y agoAnother 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.
- grannyg00se 15y agoAgain, 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.
- batista 15y agoAgain, 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.
- ypcx 15y agovar map = Object.create(null); ..will not have any of those properties. Works only in v8 though, AFAIK.
- chc 15y agoI 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.
- grannyg00se 15y agoByt 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.
- haberman 15y agoYou might not write: dict["valueOf"] since that's obviously a bad idea, but you might write: dict[user_provided_string] Since user_provided_string could be anything, you are susceptible to unexpected behavior if the string ends up being "valueOf".
- grannyg00se 15y agoBut 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.
- tolmasky 15y agoValidated 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.
- btilly 15y agoBut instead if you write: dict[ "_" + user_provided_string ] 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: my_dict[5], my_dict['5']
- syncerr 15y agoShould be able to use Type.prototype.method (e.g., Object.prototype.hasOwnProperty).