112

The following two different code snippets seem equivalent to me:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

and

var myObject = {'A': 'Athens', 'B':'Berlin'};

because they both behave the same, and also typeof(myArray) == typeof(myObjects) (both yield 'object').

Is there any difference between these variants?

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
prinzdezibel
  • 11,029
  • 17
  • 55
  • 62

8 Answers8

138

Virtually everything in javascript is an object, so you can "abuse" an Array object by setting arbitrary properties on it. This should be considered harmful though. Arrays are for numerically indexed data - for non-numeric keys, use an Object.

Here's a more concrete example why non-numeric keys don't "fit" an Array:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

alert(myArray.length);

This won't display '2', but '0' - effectively, no elements have been added to the array, just some new properties added to the array object.

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
  • 4
    myArray.length returns a numeric index/key of the last element in array but not the actual number of elements. Are properties of the Array object not the same as array values? – Dasha Salo May 17 '09 at 09:50
  • 1
    I was just trying to illustrate the intended semantics of the Array object are abused if you just treat it like a regular object. The linked article does a better job though :) – Paul Dixon May 17 '09 at 10:19
  • 15
    The next time someone says JavaScript is a good language to develop with, I'll show him this sample. Thank you. – Olivier Pons Apr 19 '14 at 08:04
  • @Olivier, what you call a "bug" can as well be an awesome "feature". You can add a tittle and description to arrays without affecting their contents or length and without having to wrap them in objects with `title`, `description` and `items` properties. It all depends on how well you know the language and how you use it. – tao Mar 09 '20 at 08:27
  • 3
    Using custom properties on Arrays is not inherently wrong. What's wrong is expecting them to act as array members once you do. They are array properties, not members, hence not affected by array methods. This is actually said by the author of the above linked article, in the comments. Now, in all fairness, I would advise against it as a practice, as it will probably confuse the hell out of people using your code. Or, if they're just starting, it will set them on a dangerous path, by power of example. But I wouldn't say JavaScript is bad because it allows stuff most don't expect to be allowed. – tao Mar 09 '20 at 08:54
  • 2
    +1 tao: if "it will probably confuse the hell out of people using your code", then this is inherently a language prone to more problems – Olivier Pons Mar 11 '20 at 11:05
14

In JS arrays are objects, just slightly modified (with a few more functions).

Functions like:

concat
every   
filer
forEach
join
indexOf
lastIndexOf
map
pop
push
reverse
shift
slice
some
sort
splice
toSource
toString
unshift
valueOf 
Casey
  • 6,166
  • 3
  • 35
  • 42
  • Although I don't think all of the functions listed are built-in every JS implementation, you got the point. The other difference would be different prototype (which is implied by those extra functions). – Rashack May 17 '09 at 09:26
5

You can add named properties to almost anything in javascript but that doesn't mean that you should. Array in javascript should be used as a list, if you want an associative array use Object instead.

Beware that if you really want to use an Array with named properties instead of Object those properties won't be accessible in a for...of loop and you might also get unexpected results when JSON encoding it to pass it around. See example below where all non-numeric indexes get ignored:

let arr = [];
let obj = {};

arr['name'] = 'John';
obj['name'] = 'John';

console.log(arr);    // will output [name: "John"]
console.log(obj);    // will output {name: "John"}

JSON.stringify(arr); // will return [] <- not what you expected
JSON.stringify(obj); // will return {"name":"John"}
resu
  • 944
  • 12
  • 21
5

Me thinks, me too metaphorical and cryptic with previous answer. Clarification follows.

An instance of Array, Boolean, Date, Function, Number, RegExp, String is an Object but enhanced with methods and properties specific to each type. For example, an array has a predefined length property while generic objects do not.

javascript:alert([].length+'\n'+{}.length)

displays

0
undefined

Intrinsically, the FF Gecko interpreter also distinguishes between Arrays and generic Objects with distinct differences evaluating language constructs.

javascript:
  ra=[  "one",   "two",   "three"]; ra.a=4;
  ob={0:"one", 1:"two", 2:"three"}; ob.a=4;
  alert(
    ra            +"\n\n"+
    ob            +"\n\n"+
    ra.toSource() +"\n\n"+
    ra.a          +"\t .toSource() forgot me! \n\n"+
    ra.length     +"\t and my length! \n\n"+
    ob.toSource());
  ps=""; for(i in ra)ps+=i+" "; alert(ps);  /* NB .length is missing! */
  ps=""; for(i in ob)ps+=i+" "; alert(ps);

displaying

one,two,three

[object Object]

["one", "two", "three"]

4    .toSource() forgot me! 

3    and my length! 

({0:"one", 1:"two", 2:"three", a:4})

and 0 1 2 a and 0 1 2 a.

Regarding the statement that all objects are functions:

It is neither syntactically nor semantically correct to use an arbitrary object instance as a function like 123() or "abc"() or []() or {}() or obj() where obj is any type other than Function, so an arbitrary object INSTANCE is not a Function. However, given an object obj and it's type as Array, Boolean, Date, ..., how did obj come to be as an Array, Boolean, Date, ...? What is an Array, Boolean, Date, ...?

javascript:
    alert([Array, Boolean, Date, Function, 
              Number, Object, RegExp, String] . join('\n\n') );

displays

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

In every case, without equivocation, the object type manifests as a function definition, hence the statement that all objects are functions! (The tongue-in-cheek is that I intentionally obscured and blurred the distinction of an object instance with that of it's type! Still, this shows "you can't have one without the other", Object and Function! Capitalization emphasizes type as opposed to instance.)

Both a functional and object paradigm seem to be fundamental to the programming and implementing of the JS interpreter low level built-in primitives, such as Math and JSON and true.

 javascript:alert([Math, JSON, true.toSource()].join("\n\n"));

displays

[object Math]

[object JSON]

(new Boolean(true))

At the time of the development of Javascript, an object-centric programming style (OOP's - Object Oriented Programming style - the "'s" is my own pun!) was in vogue and the interpreter was similarly christened with Java to give it greater credibility. Functional programming techniques were relegated to more abstract and esoteric examinations studying the theories of Automata, Recursive Functions, Formal Languages, etc. and as such not as palatable. However, the strengths of these formal considerations are clearly manifest in Javascript particularly as implemented in FF's Gecko engine (ie. .toSource()).


The Object definition for Function is particularly satisfying for it is defined as a recurrence relation! defined using it's own definition!

function Function() { [native code] }
and since a function is an Object the same sentiment holds for
function Object() { [native code] }.

Most of the other definitions quiesce to a static terminal value. However, eval() is a particularly powerful primitive and so a String can also embed arbitrary functionality.

Note again, the vernacular used above obscures object type and instance distinction.

Ekim
  • 949
  • 1
  • 8
  • 9
5

Everything in JavaScript is an object besides primitive types.

The code

var myArray = Array();

creates an instance of the Array object while

var myObject = {'A': 'Athens', 'B':'Berlin'};

creates an instance of Object object.

Try the following code

alert(myArray.constructor)
alert(myObject.constructor)

So you will see the difference is in the type of object constructor.

The instance of the Array object will contain all the properties and methods of the Array prototype.

Benny Code
  • 51,456
  • 28
  • 233
  • 198
Dasha Salo
  • 5,159
  • 5
  • 26
  • 28
2

The difference between the arrays and the other objects in JavaScript. While arrays have a magically updating length property, for objects other than the arrays there is no way to implement such a property.

var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6

Array are used to store things with an ordinal index - use it like a traditional array, stack, or queue. An object is a hash - use it for data that has a distinct key.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Parth Raval
  • 4,097
  • 3
  • 23
  • 36
  • 1
    "*for objects other than the arrays there is no way to implement such a property.*" getters, setters, and proxies can be used among other things. It's *possible* to do, just not default behaviour. – VLAZ Apr 21 '21 at 09:18
  • @VLAZ, Sorry my lake of knowledge, Please edit and correct the answer, if something went wrong. – Parth Raval Jul 31 '21 at 14:37
1

In JavaScript Arrays are special typed objects

typeof new Array(); // returns "object" 
typeof new Object(); // returns "object

Arrays used numbered Indexes and Objects used named Indexes

so we can able add named properties to Array

const arr = []
arr["A"] = "Hello" //["A":"Hello"]

console.log(arr.length) // 0 

arr.length returns 0 , because array with named indexes are prefer to call Objects

console.log(Object.keys(arr)); // ["A"]
console.log(Object.keys(arr).length); //1
Community
  • 1
  • 1
venky
  • 11
  • 2
-1

The {}-notation is just syntactical sugar to make the code nicer ;-)

JavaScript has many similar constructs like the construction of functions, where function() is just a synonym for

var Func = new Function("<params>", "<code>");
Noldorin
  • 144,213
  • 56
  • 264
  • 302
Dario
  • 48,658
  • 8
  • 97
  • 130
  • 3
    Function constructor is **NOT** a synonym for the function literal. The literal is lexically scoped while the constructor is global. `{}` is literal object notation, `[]` is literal array, I'm not sure what is the point of your answer. – Ruan Mendes Apr 21 '11 at 17:11
  • Also, declared functions are available before any code is executed, assignments using the Function constructor aren't available until the code that creates them executes. – RobG Sep 11 '14 at 02:52