66

In my script there is a need to create a hash table, and I searched in google for this. Most of the folks are recommending JavaScript object for this purpose. The The problem is some of the keys in the hash table have a "." in them. I am able to create these keys easily with the associative arrays.

I don't understand why associative arrays are bad. The first thing that is mentioned on the sites that I looked at is the length property.

I am coming from the Perl background, where I used hashes. Most common uses were to get the value from a key, check if a key exists, delete a key-value pair, and add a key-value pair. If these are my common uses, can I safely use an associative array?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
SAN
  • 2,149
  • 4
  • 25
  • 31
  • 2
    What is this associate array that you speak of? – themel Nov 09 '11 at 15:54
  • 6
    Beware, several of the answers below neglect to mention the problem of keys colliding with builtin methods: see http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/ – NickZoic Apr 19 '13 at 05:11

7 Answers7

99

In JavaScript, objects are associative arrays...there aren't separate concepts for them. You are also able to safely use '.' in a key name, but you can only access the value using the bracket notation:

var foo = {}
foo['bar'] = 'test';
foo['baz.bin'] = 'value';

alert(foo.bar); // Shows 'test'
alert(foo['baz.bin']); // Shows 'value'

If you're using them already and they work, you're safe.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Justin Niessner
  • 229,755
  • 35
  • 391
  • 521
  • 11
    Note that opposed to e.g. PHP associate arrays, the objects properties are not sorted, i.e. you can't rely on their order. – andig Sep 17 '13 at 14:06
  • 1
    I don't think you could generalize objects as associative arrays, mainly because objects won't have the methods that associative arrays have implemented. (Example: `map`, `reduce`, `filter`, etc.) – hlin117 Jun 24 '15 at 18:34
  • @hlin117 - Associative arrays (objects) don't have those methods either. Only plain Arrays have those methods. – Justin Niessner Jun 25 '15 at 02:13
  • @JustinNiessner in my node application I do have map, reduce etc. for an associative array. – velop Apr 13 '16 at 19:02
  • the problem is that ```foo.length=0``` – zeros-and-ones Feb 12 '17 at 07:07
  • If using a javascript object as a key-value map, it has to take into account that keys like "constructor", "toString" may not work properly. For example for an empty object x x["constructor"] exists or "constructor" in a is true, etc.. – Alejadro Xalabarder Dec 03 '17 at 01:35
33

In a JavaScript, an object and array are pretty much the same thing, with an array having a bit of magical functionality (autoupdating the length property and such) and prototype methods suitable for arrays. It is also much easier to construct an object than using an associative array:

var obj = {"my.key": "myValue"};

vs.

var obj = [];
obj["my.key"] = "myValue";

Therefore never use the array object for this, but just the regular object.

Some functionality:

var obj = {}; // Initialized empty object

Delete a key-value pair:

delete obj[key];

Check if a key exists:

key in obj;

Get the key value:

obj[key];

Add a key-value pair:

obj[key] = value;
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Esailija
  • 130,716
  • 22
  • 250
  • 308
  • 1
    what about to get size of an object ? – realtebo Apr 02 '13 at 05:35
  • 1
    @realtebo there is no first-class syntax for that, you can make a function for it if you need – Esailija Apr 02 '13 at 07:48
  • 2
    The part of this answer about not using an array as an associative array because it takes two lines of code instead of one is pretty misleading. That construct doesn't populate the target element, it sets a property of the array, exactly as described in the post at the same time by @Dominic Goulet and NullUserException, which IMO is the correct answer. The only reason it behaves at all like an associative array (you can reference obj["my.key"]) is that the array's properties are an object, and objects are as close as Javascript comes to having associative arrays. – enigment Feb 05 '14 at 03:27
  • 3
    I don't think it's correct to say that an array and an object are the same thing in JS. I mean, by that standard practically everything in JS is about the same thing as an object. An array allows you to set arbitrary properties just like any other type of object. However, an object by itself has no concept of ordered data. – Jason Baker Feb 20 '14 at 18:08
  • 1
    It's not so much that "object[s] and array[s] are pretty much the same thing" as it is that Arrays *are* Objects (but not vice-versa). – Ajedi32 Feb 25 '14 at 16:38
  • @Ajedi32 Well no, an object can be easily confused with an array and if you don't set out of bound indices directly there is no difference at all except the prototype which you can set with the proto setter or just use `.call`. – Esailija Feb 25 '14 at 18:00
  • 1
    @Esailija Open your browser's JavaScript console and paste this: `([] instanceof Object)`. You'll get back `true`. Now try this: `(typeof [])`. You'll get back `"object"`. In JavaScript, Arrays are Objects. – Ajedi32 Feb 25 '14 at 18:51
18

Because there is no such thing as built-in associative arrays in JavaScript. That's why it's bad.

In fact, when you use something like:

theArray["a"] = "Hello, World!";

It simply creates a property called "a" and set its value to "Hello, World!". This is why the length is always 0, and why the output of alert(theArray) is empty.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Dominic Goulet
  • 7,717
  • 7
  • 23
  • 54
  • Sure there's such thing as an associative array in javascript. There just isn't a *built-in* concept of an associative array. For example, closure has an associative array: http://docs.closure-library.googlecode.com/git/class_goog_structs_Map.html – Jason Baker Feb 20 '14 at 18:12
  • @JasonBaker The OP was referring to javascript (see tag), not google libs. Of course you can do whatever you want in javascript, and as you stated there is no such thing as *builtin* associative arrays in javascript. I thought that was obvious, but I'll update answer. – Dominic Goulet Feb 25 '14 at 16:19
9

Actually, an "associative array" is pretty much the same as an "array-like object" in ECMAScript. Even arrays are objects in ECMAScript, just with the exception to have numeric keys (which are still strings in the background) and a .length property, along with some inherited methods from Array.prototype.

So, a Perl hash and an ECMAScript object behave similarly. You might not know that you can access object properties not only via a dot, but also with brackets and strings, like

var myObj = { foo: 42 };

myObj.foo; // 42
myObj['foo']; // 42

Knowing that, you can also use keys with .

var myObj = { };
myObj['hello.foo.world'] = 42;

Of course, you can access that key only with the bracket notation.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
jAndy
  • 212,463
  • 51
  • 293
  • 348
7

You can use . in key names on JavaScript objects (AKA associative arrays) if you'd like; they're accepted without issue. The minor drawback is you can't use shortcut notations with the dotted keys, e.g.

var x = {};
x['hello'] = 'there';
alert(x.hello);

is perfectly acceptable and will pop up an alert with 'there' in it. But if you use a dotted name:

var x = {};
x['this.is'] = 'sparta';
alert(x.this.is);

will fail, as JavaScript will look for an attribute named this in the x object, which does not exist. There is only the this.is attribute.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marc B
  • 340,537
  • 37
  • 382
  • 468
3

There isn't an associative array. It's just an object.

foo.bar;    // Equivalent to...
foo["bar"]; // Looks like associative array.
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Dave Newton
  • 152,765
  • 23
  • 240
  • 286
  • Why does JavaScript permit both? Is there any actual difference between them? – EJoshuaS - Reinstate Monica Feb 28 '17 at 16:00
  • Why *shouldn't* it permit both? The only real difference is that you can use variables using "array notation", e.g., `bar = 'plugh'; foo[bar]` would return the value referenced by `foo.plugh`. – Dave Newton Feb 28 '17 at 16:21
  • It just seems blatantly redundant to me (unless I'm missing something) - http://stackoverflow.com/questions/42513889/why-does-javascript-allow-array-syntax-to-access-properties – EJoshuaS - Reinstate Monica Feb 28 '17 at 16:24
  • 1
    @EJoshuaS My only response is "so what?" Dot access is cleaner, bracket access allows other constructs. I don't see an issue with the "redundancy" (in quotes because they allow different uses). ¯\_(ツ)_/¯ – Dave Newton Feb 28 '17 at 17:01
2

For the sake of convenience of using data, there should be no difference between an object and an array. You can think of it as an object or you can think of it as an associative array. At the end, you can just think of everything as data.

  • For PHP, [ ] accepts 0, 1, or more items(array), and it is called an associative array. It is JSON in PHP's coat:

    $data = ["message"=>[ "id"=>405, "description"=>"Method not allowed.", "detail"=>[]], "object" => []];

  • For JavaScript, { } accepts 0, 1, or more items(array), and it is called an object. This data format is JSON:

    data = {"message": { "id":405, "description":"Method not allowed.", "detail" : {}}, "object" : {}};

I just call them data. The simplest way to describe data is JSON, or its variants.

Luo Jiong Hui
  • 4,526
  • 2
  • 21
  • 15