38

Are arrays merely objects in disguise? Why/why not? In what way(s) are they (such/not)?

I have always thought of arrays and objects in JS as essentially the same, primarily because accessing them is identical.

var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';

console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);

Am I mislead/mistaken/wrong? What do I need to know about JS literals, primitives, and strings/objects/arrays/etc...?

Are arrays/objects merely strings in disguise? Why/why not? In what way(s) are they (such/not)?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • 4
    `var arr = ['you':'them'];` this isn't valid syntax – Matti Virkkunen Feb 19 '11 at 02:07
  • 2
    @Robert Harvey - I am trying to clarify my understanding. Does notation denote significance? Are "arrays" fundamentally different from objects, strings, etc... in Javascript? I think it's a fair inquiry. – Jared Farrish Feb 19 '11 at 02:08
  • @Martti - Very true. Is that the principle difference then, that Javascript arrays are always indexed arrays, versus associative arrays (or objects)? – Jared Farrish Feb 19 '11 at 02:11
  • The Ecmascript Language Specification is here: http://www.ecma-international.org/publications/standards/Ecma-262.htm. Ecmascript and Javascript are essentially the same language. All of the EcmaScript and Javascript language specifications I have been able to find all say that Arrays are objects. – Robert Harvey Feb 19 '11 at 02:16
  • @Robert Harvey - I appreciate it. I'm looking for guidance, an answer in the sense of "this is the best way to understand". I'm not sure I can find that answer in a standard, although it is useful for understanding. I would also note I don't think this has been answered sufficiently in SO. I'm hoping someone gets inspired and really goes for it in an answer. – Jared Farrish Feb 19 '11 at 02:19
  • I think what you might be looking for is a better understanding of "object orientation" versus "primitives", not Javascript language features per se. – Robert Harvey Feb 19 '11 at 02:20
  • @Robert - No, not really. This is very specific to Javascript. I'm looking for a canonical response that clarifies meaning here. "Fact" is the standard; help me understand *truth*. – Jared Farrish Feb 19 '11 at 02:27
  • The language also has the wonderful oddity that typeof [] == 'object'. A poor design decision that causes further confusion. – leebriggs Feb 19 '11 at 02:31

7 Answers7

52

Arrays are objects.

However, unlike regular objects, arrays have certain special features.

  1. Arrays have an additional object in their prototype chain - namely Array.prototype. This object contains so-called Array methods which can be called on array instances. (List of methods is here: http://es5.github.io/#x15.4.4)

  2. Arrays have a length property (which is live, ergo, it auto-updates) (Read here: http://es5.github.io/#x15.4.5.2)

  3. Arrays have a special algorithm regarding defining new properties (Read here: http://es5.github.io/#x15.4.5.1). If you set a new property to an array and that property's name is a sting which can be coerced to an integer number (like '1', '2', '3', etc.) then the special algorithm applies (it is defined on p. 123 in the spec)

Other than these 3 things, arrays are just like regular objects.

Read about arrays in the spec: http://es5.github.io/#x15.4

mwhs
  • 5,878
  • 2
  • 28
  • 34
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • "arrays are just like regular objects" - That's interesting. Arrays, other than a few methods decorating them, are objects, and objects are...? Especially if an associative array is really just "cast" into an object magically. Are associative arrays still arrays in this sense? (I apologize in advance if my use of cast is incorrect.) – Jared Farrish Feb 19 '11 at 02:59
  • @Jared In JavaScript, **all** objects are associative arrays. – Šime Vidas Feb 19 '11 at 03:04
  • @Šime Vidas - So why have an array object? I'm just wondering, is it to expose the .length property? They seem to be so similar. – Jared Farrish Feb 19 '11 at 03:06
  • 1
    @Jared Use arrays when the member names would be sequential integers. Use objects when the member names are arbitrary strings or names. – Šime Vidas Feb 19 '11 at 03:11
  • @Šime Vidas - But I just come back to the question, *why*? If they're the same, with middling differences, what makes one "superior" to others in different situations? Could we forget about JS arrays and just embrace objects? Should we? – Jared Farrish Feb 19 '11 at 03:15
  • @Jared One scenario where arrays are preferred is when you have a list of non-named items. Like so: `['Peter', 'Mike', 'John']`. Here you have an array with three items (which are strings). With regular objects, you would have to name each item individually, like so: `{name1: 'Peter', name2: 'Mike', name3: 'John'}`. – Šime Vidas Feb 19 '11 at 03:25
  • @Šime Vidas - That's true. But is declaring it an array better than declaring it an object to begin with? I suppose at this point its obvious that non-indexed arrays are not objects. Is that right? – Jared Farrish Feb 19 '11 at 03:31
  • @Jared What do you mean by non-indexed array? However, all arrays are objects! – Šime Vidas Feb 19 '11 at 03:34
  • @Šime Vidas - I mean "associative" arrays. – Jared Farrish Feb 19 '11 at 03:35
  • @Jared As I said above, in JavaScript, objects are associative arrays. – Šime Vidas Feb 19 '11 at 03:38
  • @Šime Vidas - So... Associative arrays are objects (and not arrays)? – Jared Farrish Feb 19 '11 at 03:45
  • @Jared Associative arrays is a concept that goes beyond JavaScript. Read here: http://en.wikipedia.org/wiki/Associative_array In JavaScript, objects, ergo, values of the type Object have the characteristics of associative arrays. – Šime Vidas Feb 19 '11 at 03:51
  • @Šime Vidas - No, I think it has a lot of relevance, especially if JS is naturally converting an "array" into an "object" if it becomes too "complex" to contain indexes only. In the realm of JS, do associative arrays always == objects? – Jared Farrish Feb 19 '11 at 03:59
  • 1
    @Jared 1. JavaScript does not convert arrays into objects. Arrays can contain non-indexed properties just like objects. In fact, arrays can do everything that regular objects can do (and a few things more). 2. In the realm of JavaScript, there exist only objects and primitive values. Only those two things. And objects have the characteristics of associative arrays. 3. BTW, I found a good definition of an object in JavaScript: An object is a collection of properties. – Šime Vidas Feb 19 '11 at 04:03
  • @Šime Vidas - "JavaScript does not convert arrays into objects. Arrays can contain non-indexed properties just like objects." And then... "In the realm of JavaScript, there exist only objects and primitive values" How do these two statements jibe? Is this possible? – Jared Farrish Feb 19 '11 at 04:07
  • @Šime Vidas - Oh now, that's fascinating stuff. Is a regular object different from any other object (such as an Array)? Can you see why I ask these questions? I just want to understand. Help me. – Jared Farrish Feb 19 '11 at 04:16
  • @Jared All objects in JavaScript have a set of base features (they are called *internal properties* in the specification). If you do this: `var x = {};`, you will create a basic object that has these basic features. However if you do this: `var y = [];`, you will create an array which is a special kind of object that has all the basic features, but also a bunch of additional special features. – Šime Vidas Feb 19 '11 at 04:23
  • @Šime Vidas - So by using the [] notation, you're invoking an object non-primitive type with special methods meant for indexed arrays? Such as slice, length, etc...? In essense, {} (plus array_methods) – Jared Farrish Feb 19 '11 at 04:27
  • @Jared Yea, in essence. `:)` However, rephrase this *"invoking an object non-primitive type"* to this *"creating an instance of the type Object"*. – Šime Vidas Feb 19 '11 at 04:32
  • Arrays have something fundamentally special that is not listed in this answer: Only native Array return true for `Array.isArray`. That is more special than any of the points made here (since these could all apply to other objects). – Kaiido Mar 13 '19 at 02:02
13

Objects are an unordered map from string keys to values, arrays are an ordered list of values (with integer keys). That's the main difference. They're both non-primitive, as they're composed of multiple values, which also implies pass-by-reference in JavaScript.

Arrays are also a kind of object, though, so you can attach extra properties to them, access their prototype and so on.

In your revised example, you're only taking advantage of the fact that an array is actually an object, i.e. you can set any property on them. You shouldn't do that. If you don't need an ordered list of values, use a plain object.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
  • That last "If you don't need an ordered list of values, use a plain object." is interesting, Matti. Why? – Jared Farrish Feb 19 '11 at 02:16
  • @Jared: Because there is no need to create an array if you're not going to use the functionality offered by it. It's only confusing. – Matti Virkkunen Feb 19 '11 at 02:18
  • @Matti - Yes, but I'm looking for context. Help me understand *why*. Is it overhead? Is it practice? Is it good common sense? What makes it worthwhile to ditch arrays and go with objects? Does it matter? Assume I don't understand the difference. I believe you have the knowledge, but help me understand why it's *significant*. – Jared Farrish Feb 19 '11 at 02:22
  • 1
    @Jared: When you say "array", any programmer will assume you need an ordered list. If you don't need one, saying "array" is only going to confuse anybody reading your code. From a technical point of view it shouldn't make much of a difference, the overhead, if any, should be insignificant. Also, one thing: Do you use PHP a lot? – Matti Virkkunen Feb 19 '11 at 02:23
  • @Matti - "any programmer" Explore this. So many start with Javascript. I think this is important, because it could expose something that's underlying within Javascript, and a BIGGER MEANING. Help me understand why. – Jared Farrish Feb 19 '11 at 02:26
  • 1
    @Jared: I'm sorry, but I do not understand what you want me to help you understand. – Matti Virkkunen Feb 19 '11 at 02:27
  • @Matti - Begin from the beginning. What is a variable in Javascript? A primitive, the only primitives that "make sense" are String, Boolean and Number. So how does Javascript keep objects, arrays? Why/how do they differ? What does each mean, when should I use each? Coming from PHP, we make no differentiation between indexed and associative arrays, they are the "same". Is this meaningful? Just step through it, explaining each step. – Jared Farrish Feb 19 '11 at 02:31
  • 1
    @Jared: No. I'll rather go to sleep. One thing though; you should make a clear distinction between a variable and a value. They're two different things. If you want all the nitty-gritty details about how objects work, go read the ECMAScript standard (I think I saw a link to it in a comment above) – Matti Virkkunen Feb 19 '11 at 02:33
  • @Matti - I think you have missed an opportunity to speak to a large group of learners. Sure, as I specified above, the standard explains much, but I'm looking for a meaningful narrative, not a dry script with facts. How does the standard actually apply in reality? From a knowledgeable, learned person? – Jared Farrish Feb 19 '11 at 02:37
  • @Matti - And, I would like to say, I don't think this would have been too lengthy (as I imagine an answer being), although without an expert hand, it could have got messy. If I knew more, or was more confident, I would answer my own question. As you can see, I don't ask too many, for good or ill. – Jared Farrish Feb 19 '11 at 02:42
  • @Jared Watch this: http://video.yahoo.com/video/play?vid=111593 and this: http://video.yahoo.com/video/play?vid=111594 and this: http://video.yahoo.com/video/play?vid=111595 and this: http://video.yahoo.com/video/play?vid=111596 – Šime Vidas Feb 19 '11 at 02:51
  • @Šime Vidas - That's a good deal of video. I'll definitely give them a viewing, if you think I should. – Jared Farrish Feb 19 '11 at 02:55
  • 1
    @Matti Stack Overflow is pretty terrifying sometimes. – ClosureCowboy Feb 19 '11 at 03:30
7

Strings can be either primitive or objects, depending on how they were declared.

var str = 'yes';

Gives you a primitive, while,

var str = new String('yes');

will give you a String object.


All arrays are the same (Whether or not they were defined with [] or new Array()), are of the type object and inherit from the "Array" object's prototype. There aren't real classes in Javascript, everything is an object, and there's a system defined object called Array. It has a property called 'prototype' (of type object), and when you use the new keyword on an object with a prototype property, it creates an instance with a reference to the contents of the prototype and stores it in your variable. So all arrays you've ever used in Javascript are objects and instances of Array's prototype property.

In any case, although arrays really are objects, they behave like arrays because of their useful properties and functions (Such as length, slice, push etc).

Another note, although I said there are no classes, when you do this:

console.log(Object.prototype.toString.call(your_object));

it will give you a string in the form [object Object]. But what's useful is that when you call it with an array, you get [object Array] same with functions which give [object Function] and a number of other system defined types, which assists in differentiating between normal objects and arrays (Since the typeof operator will always just return the string 'object').

Try this

var a = Array;

and go into firebug and examine the contents of a, especially it's 'prototype' property.

Edit: Changed the wording a bit, to be more correct. In fact when you use the new keyword, it creates an instance which references the prototype object. So any changes made to the prototype after the instance's declaration, will still affect the instance.

Edit: In answer to your latest revised question (are arrays/objects actually strings in disguise): No. They are objects, as I've explained. Strings are either a primitive type, or an object type (An instance of the String object) which contains the primitive equivalent as one of it's properties.

aiham
  • 3,614
  • 28
  • 32
  • 2
    @aiham *... and when you use the new keyword on an object with a prototype property, it creates a clone of the contents of the prototype and stores them in your variable.* This is not true. The contents of the prototype object are not cloned, but the instance object that is created just has a reference to that prototype (and its methods). – Šime Vidas Feb 19 '11 at 02:26
  • I apologise for my incorrect wording. You're right, it references the prototype's contents. So if the prototype is modified after your instance object is created, the instance object will also be affected. I will modify my answer. – aiham Feb 19 '11 at 02:27
  • "So all arrays you've ever used in Javascript are objects and instances of Array's prototype property." That's a fascinating statement. – Jared Farrish Feb 19 '11 at 02:47
  • To your second edit, if there is no primitive type Object, how do Objects relate to Javascript? Wouldn't they then be strings in memory? I don't see a way of relating back the primitive types of String, Boolean and Integer. Does that make sense? – Jared Farrish Feb 19 '11 at 02:54
  • Indeed it is. I've only gotten interested in Javascript prototypes recently, and it's been really intriguing playing around with it all. You can make some pretty powerful applications by taking advantage of objects and prototypes. You should read some things Douglas Crockford has to say about Javascript ( http://javascript.crockford.com/ ), a lot of is quite useful (Some is a bit over the top). – aiham Feb 19 '11 at 02:56
  • Well I'm not sure how objects are stored in memory, but I'd guess it would depend on the browser. A Javascript developer doesn't need to know about memory to develop in Javascript. It's a much lower level issue than Javascript deals with. You don't have access to memory or pointers in it like other lower level languages. (You can set variables for garbage collection with 'delete' though). It's all done for you. If you are that interested in how the browser stores objects in memory, then you'd be better served asking in an open-source browser development community, such as Mozilla's. – aiham Feb 19 '11 at 03:05
  • "A Javascript developer doesn't need to know about memory to develop in Javascript" - @aiham - I think you should incorporate this into your answer. Is this really not part of the answer, the puzzle? – Jared Farrish Feb 19 '11 at 03:12
  • Firstly, let me rephrase that, 'doesnt need to know about pointers and how memory is stored'. Of course you do have to worry about memory and taking too much of it. – aiham Feb 19 '11 at 03:16
  • Secondly, I didn't realise that's what you were asking. I just thought you wanted to know how to use Objects in the Javascript language. Not how the browser stores them in memory after parsing your script. I'd say that you should change your question to be exactly that, and add a few more tags related to which browser you want to know about and in what language the browser was written, because I'm sure those would have an effect. – aiham Feb 19 '11 at 03:18
  • @aiham - No, that's not what I was asking specifically, merely an attribute of what I wanted explained. If a primitive type `object` does not exist in JS, are objects Strings? What's the definitive answer? Can you explain? I would note my understanding of arrays were that they were objects in memory, regardless. – Jared Farrish Feb 19 '11 at 03:21
  • @Jared There are 5 primitive types in Javascript: Number, String, Boolean, Null, Undefined. ... Object is not a primitive type. – Šime Vidas Feb 19 '11 at 03:32
  • @Šime Vidas - So what are they? – Jared Farrish Feb 19 '11 at 03:34
  • @Jared Array are objects. Arrays are values of the type Object. (I'm saying this for the third time. `:)`) – Šime Vidas Feb 19 '11 at 03:37
  • @Šime Vidas - And I am saying again, what are objects? Strings? And I terribly conflicted? – Jared Farrish Feb 19 '11 at 03:43
  • @Jared String is a primitive type. Object is a different type. Objects are not Strings, the same way as Strings are not Numbers. They are just two different types. – Šime Vidas Feb 19 '11 at 03:53
  • @Šime Vidas - Yes, but what type? There has to be a bridge here. If an object is not a String, Integer, or Boolean, what is it? What do I not know? – Jared Farrish Feb 19 '11 at 03:56
  • @Jared The type is named Object. Objects are values of the type Object. – Šime Vidas Feb 19 '11 at 03:59
  • @Šime Vidas - So how does Javascript explain a type that is not a primitive? – Jared Farrish Feb 19 '11 at 04:01
  • @Jared So your question is: How is it possible that non-primitive types exist? But why wouldn't they exist? In JavaScript, there are 5 primitive types, and one non-primitive type. – Šime Vidas Feb 19 '11 at 04:07
  • @Šime Vidas - "one non-primitive type" = Objects? – Jared Farrish Feb 19 '11 at 04:09
  • @Jared Yes, the type Object is the **one and only** non-primitive type in JavaScript. – Šime Vidas Feb 19 '11 at 04:14
6

Arrays are not primitives in Javascript, they are objects. The key difference is that as a result, when you pass an array to a function it is passed by reference, not by value.

So yes! Arrays are objects in javascript, with a full blown Array.prototype and everything (don't touch that though...)

The confusion comes from the fact that javascripts lets you access object attributes in two ways:

myObj.attribute or myObj["attribute"]

Really what makes an array an array has nothing to do with the way you store data -- any object can store values using the syntax you use to store the array -- what makes an array an array is the fact that array methods (e.g. shift() and sort()) are defined for Array.prototype.

slifty
  • 13,062
  • 13
  • 71
  • 109
1

Trying to be brief with what I believe to be of the most significance: arrays have a number of methods that objects do not. Including:

  • length
  • push
  • pop

An object declared as var x = {foo:bar} has no access to a .length() method. They are both objects but with the array as a sort of superset with methods mentioned as above.

I don't feel I this is even close to being of Crockford standard in terms of explanation but I'm trying to be succinct.

If you want to get some quick results, open up Firebug or your javascript Console and try Array.prototype and Object.prototype to see some details

Update: In your example you declare an array and then do:

foo['bar'] = 'unexpectedbehaviour';

will produce unexpected results and won't be available in simple loops such as:

var foo=[0,1];
foo['bar'] = 2;

for(var i=0;i<foo.length;i++){
    console.log(foo[i]);
}

//outputs: 
//0
//1

An array can accept foo['bar']=x or foo.bar=y like an object but won't necessarily be available to be looped through as highlighted above.

Not that I'm saying that you can't iterate through the properties of an object, just that when working with an Array, you're utilising that unique functionality and should remember not to get confused.

connrs
  • 283
  • 1
  • 7
  • @connrs Not true. Arrays can have properties just like any other objects: `var arr = []; arr.foo = 'Totally fine!';` – Šime Vidas Feb 19 '11 at 02:28
  • Careful connrs. Arrays have those methods because they ARE objects, whose prototype has been given those functions. – slifty Feb 19 '11 at 02:35
  • @Šime Vidas: Indeed but `var foo=[0,1]; foo.bar=2; for(var i=0;i – connrs Feb 19 '11 at 02:39
  • @slifty: Indeed. Array literals are objects as I mentioned above. arrays inheriting from the Array prototype methods such as length push and pop which are absent for pure Object literals – connrs Feb 19 '11 at 02:41
  • @connrs In your answer you say that this is invalid: `foo['bar'] = 'totallyinvalid';` But that is not true. It is valid. That's my point. – Šime Vidas Feb 19 '11 at 02:43
  • Ah. I suppose pointing out that it would produce unexpected results is a better angle to take. Editing it now – connrs Feb 19 '11 at 02:46
  • @connrs - I swear I used to get an error when using foo.var without first declaring foo['var']. I SWEAR. – Jared Farrish Feb 19 '11 at 03:28
1

In JavaScript you have a few types, everything else is an object. The types in JavaScript are: boolean, number, and string. There are also two special values, "null" and "undefined".

So the quest "is a JavaScript array an object?" is slightly ambiguous. Yes, a JavaScript array is an "object" but it is not an instance of "Object". A JavaScript array is an instance of "Array". Although, all objects inherit from Object; you can view the inheritance chain on the MDC. Additionally, arrays have slightly different properties than an object. Arrays have the .length property. They also have the .slice(), .join(), etc methods.

Douglas Crockford provides a nice survey of the language's features. His survey discusses the differences you are asking about. Additionally, you can read more about the difference between literals and constructors in question #4559207.

Community
  • 1
  • 1
James Sumners
  • 14,485
  • 10
  • 59
  • 77
  • Now see, this jibes with what I understand. The three types. But how to explain `Object`, in which everything else is `constructed`, except arrays? Are we only talking about default method prototypes? "Yes, a JavaScript array is an "object" but it is not an instance of "Object" This gets to the heart of what I am inquiring about. – Jared Farrish Feb 19 '11 at 03:04
  • And yes, Crockford is the reason Javascript is taken seriously, IMO. He's been organizing sanity on the Javascript front for too long to remember (at least since 2004, earlier?). – Jared Farrish Feb 19 '11 at 03:07
  • @Jared You know Crockford but haven't watched his most fundamental JavaScript video series? Go watch it now! :) – Šime Vidas Feb 19 '11 at 03:35
  • @jsummers - So Arrays are fancy character arrays with self-defined special methods? – Jared Farrish Feb 19 '11 at 03:38
  • @Šime Vidas - Yeah, I know. Crockford is god. The point here is to extract as much meaning as possible, as opposed to my own stochastic learning processes. I want there to be a meaning that would have been meaningful for me, back then (Thanks Thau!). – Jared Farrish Feb 19 '11 at 03:41
  • ES6 contains a new primitive data type also: Symbol – Hart Simha Sep 14 '15 at 22:09
0

Arrays are Objects, but of a specialized nature. Objects are collections of values indexed by keys (in Javascript notation, {'key': 'value'}), whereas Arrays are Objects whose keys are numeric (with a few functions and properties). The key difference between them is obvious when you use a for each loop--an Object will iterate over all the values in its properties, whereas an Array will return the keys instead. Here's a link to a JSFiddle demonstrating the difference--notice that the first for each, which uses an array, returns the indexes, not the values; in contrast, the second for each returns the actual values at those keys.

Jeff Hubbard
  • 9,822
  • 3
  • 30
  • 28