Is everything in JavaScript an Object?



I have always found this statement confusing: “Everything in JavaScript is an Object”. What did they mean by this? How can a Function or an Array at the same time be an Object? Before we tackle this question, we need to understand how the different Data Types are categorized.

In JavaScript, there are two Data Types: Primitives and Objects. (Object Types are also sometimes referred to as Reference Types). 1

Primitive Object
Number Function
String Object
Boolean Array
Symbol
null
undefined

Based on this categorizing, the simple anwser is no, not everything in JavaScript is an Object. Only values that belong to that Type are Objects. Another way of looking at it is, any Type that isn’t a Primitive Type is an Object Type. But what is it that differentiates Primitives from Objects? And more importantly, what do people really mean when they say “everything” or “almost everything” is an Object”? There are two main distinctions: mutability, and comparison.

Mutability

From my experience, what people really mean when they talk about values being “object like” is their mutability. More specifically, they’re talking about the ability to add and remove properties. For example, because Functions and Arrays belong to the Object Type you can add properties to them just like you would an object literal.

var func = function() {};
func.firstName = "Andrew";
func.firstName; // "Andrew"

var arry = [];
arry.age = 26;
arry.age; // 26

This opens the door to all sorts of fascinating use cases, and is really the key to understanding how Prototypes and Constructors work.

However because Primitive Types are immutable, we’re unable to assign properties to them. 2 The parser will immediately discard them when attemping to read their value.

var me = "Andrew";
me.lastname = "Robbins";
me.lastname; // undefined

var num = 10;
num.prop = 11;
num.prop; // undefined

At this point, I think it would be useful to examine things at a more fundamental level. With regards to primitives, what does it really mean to say that their values cannot be changed? Consider the following code:

1 = 2; // ReferenceError

This might seem like a silly example, but I think it shines a much needed light on exactly what we’re talking about when we talk about mutability. When you type the number 1 into the JavaScript console, the compiler assigns that piece of data to the Primitive data type. Therefore when you attempt to change the number 1 to the number 2, it fails and probably has a heartattack.

Comparison and passing around

Besides mutability, another important distinction between Primitive Types and Object Types is the way they’re compared and passed around within the program. Primitive Types are compared by value, while Object Types are compared by reference. What does this mean? Let’s look at Primitives first. Consider the following code:

"a" === "a"; // true

This is true because the value “a” is equal to “a”. Simple. However what happens when we introduce variables into the picture? Nothing has changed except that we’re now storing our Primitive Types into variables.

var a = "a",
    b = "a";

a === b; // true

Since Primitive Types are compared by value, the result will true. The value of the variable a is exactly equal to the value of the variable b. In other words, “a” equals “a”. Aristotle would be proud. However look at this. If we apply the same example to an Object Type, we get the opposite result.

var a = {name: "andrew"},
    b = {name: "andrew"};

a === b; // false

Why is this? Object Types must reference the same object in order for its comparison to be true. In the example above, we’re creating a new object for the variable b. As David Flanagan puts it:

“…we say that objects are compared by reference: two object values are the same if and only if they refer to the same underlying object.” 3

Now, what happens when we pass these values around?

var a = {name: "andrew"},
    b = a;

b.name = "robbins";

a === b; // true

This might seem strange at first, but look closer at what’s happening. Because objects are part of the Object type, it’s values are compared and passed by reference. Reference to what? Reference to the same underlying object. In the above example, we’re setting b equal to a. We didn’t create a new object. We’re simply creating a reference to another object. A different way of looking at it is that we’re pointing the variable b to a. Therefore when we mutate the “name” property on b, we’re at the same time mutating the “name” property on a.

Back to Primitives, how would the same example apply to them?

var a = "Andrew",
    b = a;

b = "Robbins";

a === b; // false

Remembering that Primitives are compared and passed by value, when we set b equal to a, we’re actually creating a new copy of a. Therefore when we change the value of b and then compare it to a, the value is not the same anymore.

Wrapper Objects

Some of you may be wondering, “Ok, if Primitives aren’t Objects then why can I call methods on them?” The answer is Wrapper Objects.

When you attempt to call methods on a Primitive, JavaScript does a magic trick behind the scenes. It takes your Primitive value and converts it to a temporary Object using a constructor function. 4 The decision of which constructor function to use will depend on the Primitive value you’re attempting to change. For example, calling .length on a string will use the built in String() constructor to temporarily change the Primitive to an Object—allowing you to use the length method to mutate it. This temporary Object is called a Wrapper Object. 5

Interestingly enough, the two Primitive values null and undefined do not behave this way. Trying to call methods on these values will result in a TypeError.

We can use the typeof keyword to show the difference.

typeof "s"; // "string"
typeof new String(s); // "object"

As a sidenote, it’s useful to know that there’s a well-documented bug 6 in JS compilers which returns “object” when executing typeof null.

typeof null // "object"

Considering that JavaScript was written in 10 days 7, I’m not going to lose any sleep over it =)

It’s also useful to know that properties on Primitives are read-only, and temporary.

var hello = "hello";
hello.slice(1); // "ello" (Here we're actually calling slice not on hello, but of a copy of hello)
hello; // "hello"

Summary

JavaScript values can be categorized into two Types: Primitives and Objects. The Primitive Types are String, Number, Boolean, Symbol, undefined and null. The Object Types are Function, Object and Array.

The two distinctions between Primitives and Objects are their mutability and the way they’re compared and “passed around” within the program.

Primitives are immutable. Another way of saying this is that their values can’t be changed. On the other hand, Objects are mutable. Their values can be updated and changed.

Primitives are compared by value. When assigning one primitive to another using variables, a copy is made. Objects on the other hand are compared by reference. Reference to what? Reference to the underlying Object. When assigning one Object to another, a reference / pointer is created. At this stage, mutating a value on one Object will update the value on the other Object.

When attempting to call methods on Primitive values, JavaScript uses a Wrapper Object to temporarily coerce the Primitive. The resulting Object is read-only and garbage collected after execution.

In the next section, we’ll go over how these Types fit into the bigger picture by analyzing Prototypes, Constructors, and Inheritance.

Update: 11/8/14

Recently there was a discussion over at https://javascriptkicks.com/stories/1669 regarding the performance of both Objects and Primitives. @drewpcodes wanted to know which approach would be faster: storing floating point numbers in Primitive form or Objects form? I was curious to know as-well so I wrote a small program to test it out. You can find the code I used here: http://jsfiddle.net/pmqortov

I created two arrays: one array stored the data as Objects, and another stored the data as Primitives. Based on @drewpcodes use-case, the data I used was 150 floating point numbers. I also decided to limit both arrays to 150 entries so it wouldn’t freeze my computer.

I then iterated over the arrays and saved a timestamp before and after every iteration. Then I did a little math on each timestamp and found the average in ms. For the sake of accuracy, I looped 5000 times for each instance. I noticed increasing this number would freeze Chrome. =)

Surprisingly enough, the list containing the data stored as Objects was actually 2ms faster then stored as Primitives! Here were the actual numbers:

// List with Objects 
// Average execution across 5000 repetitions: 16.8528 ms 
 
// List with Primitives 
// Average execution across 5000 repetitions: 18.2898 ms 

At this point I don’t have an opinion either way of which method is best for storing your data. It could be that at higher volumes the Object method would be advantagous, but I’d like to see more evidence first.

Cheers!

  • InfiniteNovice

    is worth noting that Strings can be either primitive or Object if we use the String constructor, in that case, we are comparing by reference instead of by value.
    the issue now is, why string literals, not being Objects, have methods? i’m just a js beginner trying to figure out the weird parts of the language. Nice blog and i’m sorry for my english :p

    • chris-l

      Is what Anton said. (I didn’t knew it was called boxing)

      What happens is that when you try to access a property or method from “something”, and JavaScript realizes that this “something” is actually a primitive, it creates an object that uses the primitive in the constructor and then uses this new object to access the property.

      So when you do ‘console.log(‘hello’.length);’, JavaScript notices that ‘hello’ is a primitive and creates an object.

      Internally, what it actually does is something similar to this:

      ‘console.log((new String(‘hello’)).length);’

      After that, it dumps the object. (And that is the reason you can add properties to the primitive and then they disappear; the object was temporally created, the properties were added and then the object was dumped after that)

      As an experiment, try this:

      // A function to save the temporal object!
      String.prototype.save = function(name) { window[name] = this; };

      ‘hello’.save(‘helloObject’);

      And now you’ll have a global var called ‘helloObject’ which is instance of String and was created with the ‘hello’ primitive.

      • arobbins

        Fantastic answer Chris, thanks. I’m going to add this as an update.

    • arobbins

      Thanks for the kind words Infinite!

  • I’m pretty sure JS has implemented primitives the same way Java did.

    In Java, you have boxing and unboxing. You can create a string, number, whatever with the class constructor, but you can also create it the primitive way.

    Casting/creating a primitive to the object type in Java – (String, Integer, Double…), in JS – (String, Boolean, Number..) is called boxing and doing the opposite – unboxing.

    The advantage of boxing a primitive is having the ability to use the boxed class’ methods, like – charAt(), indexOf(), concat() and etc.

    • arobbins

      Really great info, thanks for sharing Anton.

  • Pingback: Is everything in JavaScript an Object?()

  • I just want to notice that any primitive in JavaScript could be an Object too. And that’s the valueOf() method of an Object which returns the primitive value (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf).

    For example:

    var a = new String('hello');
    a.foo = 'bar';

    console.log(a); // String object like {0: "h", 1: "e", 2: "l", 3: "l", 4: "o", foo: "bar", length: 5, [[PrimitiveValue]]: "hello"}
    console.log(a.valueOf); // 'hello'

    So actually what interpreter does you use literals is creating an Object and then returning its primitive value.

  • *So actually what interpreter does when you use literal notation:

    1. Creates an object
    2. Returns its primitive value

    That means that everything in JavaScript is an Object 🙂

    • arobbins

      Hey Dmitri, thanks for the comment. I’ve updated the article with a section on Wrapper Objects.

      I know it’s purely academic, but I would challenge your conclusion. While it’s true that calling methods on Primitive values temporarily creates an Object, I think it’s important to know that Primitives don’t begin that way. There’s a vital difference between an “all natural” Primitive value and a coerced Primitive value.

      • chris-l

        Indeed. They don’t start as objects that are used to return the primitive value.
        Instead, they start as primitives values and they stay as primitives, and only will be wrapped into an object if they are used as objects. (but the value is not converted to an object, just temporarily wrapped into one).

        From mdn:

        “String literals (denoted by double or single quotes) and strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.

        JavaScript automatically converts primitives to String objects, so that it’s possible to use String object methods for primitive strings. **In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.**”

        Source:
        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String?redirectlocale=en-US&redirectslug=JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects

        • arobbins

          Great info, thanks Chris.

  • Javier Alba

    Great article. It may be worth to mention somewhere that, although it is a primitive, when you check for the type of null you will get “object” due to a bug in ECMAScript.

    • arobbins

      Ah great point Javier. I’ll add this as an update.

  • lpsantil

    The first example under “Mutability” is incorrect. “func.name” is the value of name provided after the function keyword (empty string in your example). It’s also a property of all Functions, whether created by new Function, declaration in scope, and declared in assignment (as your example).

    null (incorrectly called Null) and undefined (incorrectly called Undefined) are not primitive types. They are values and valid values for any Object (var).

    Symbol’s are not primitive types. They’re Objects. The Moz doc is misspoken.

    The typeof operator is also sometimes broken. [http://www.2ality.com/2011/11/improving-typeof.html]

    • arobbins

      Thanks for pointing out the spelling mistakes and function name typo.

      Based on the sources I referenced in the article, null and undefined are indeed Primitives. MDN also states this https://developer.mozilla.org/en-US/docs/Glossary/Primitive

      • lpsantil

        Like I said, the Moz doc is misspoken, even wrong (at least from a Classical Computer Science perspective). Florian (Moz doc author) states, “A primitive (primitive value, primitive data type) is data that is not an Object and does not have any methods.” [0]. In my opinion, that’s a horrible and confusing conflation of two distinct concepts (types [1][2] & values [3]). values are expressions which can have no further evaluation [3]. types are sets of valid values and the operations that can be performed on them [1], including how values are/can be stored.

        Crockford’s treatment of the data types [4] in JS gives a better name to null and undefined, special values. Symbol probably belongs here as well. Especially when you consider how these values are created and used, special value is better name for them than primitive value (since they don’t behave like other primitive values in JS).

        null can only be created by assignment but 1) forces the internal type of the label (var) it is assigned to become an Object that 2) has no properties and 3) has a frozen property list.

        undefined can be created by adding a var to scope or by assignment.

        I see you still list Symbol as Primitive type. Mozilla seems confused about it themselves in one document calling it a Primitive type and then in another [5][6]. It seems like poorly thought out, poorly executed way to get faster property/index access without implementing pointers or the with statement. At this point, I’m not a fan of it. Especially since they’re not JSON’able [5].

        [0] https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Summary
        [1] http://en.wikipedia.org/wiki/Data_type
        [2] http://en.wikipedia.org/wiki/Primitive_data_type
        [3] http://en.wikipedia.org/wiki/Value_(computer_science)
        [4] http://javascript.crockford.com/survey.html
        [5] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
        [6] https://developer.mozilla.org/en-US/docs/Glossary/Symbol
        [7] http://en.wikipedia.org/wiki/Lisp_(programming_language)#Atoms

        • lpsantil

          Meant to say in that last paragraph,

          Mozilla seems confused about it themselves in one document calling it a Primitive type and then in another demonstrating that can only be created like objects [5][6]. It seems like poorly thought out, poorly executed way to get faster property/index access without implementing pointers or the with statement. Real atoms would have been better [7]. At this point, I’m not a fan of it. Especially since they’re not JSON’able [5].

  • Test

  • Pingback: webinar jeo review()

  • Pingback: informative post()

  • Pingback: Free hosting()

  • Pingback: Domain Reseller()

  • Pingback: deadman runescape bot software tribot.org()

  • Pingback: life insurance lawyer attorney()

  • Pingback: check my blog()

  • Pingback: magicbox speaker()

  • Pingback: ananinaminakas()

  • Pingback: economics tuition()

  • Pingback: anal-bleaching()

  • Pingback: telephonic court appearance()

  • Pingback: see this site()

  • Pingback: showbox for PC()

  • Pingback: thai 50 steroids()

  • Pingback: Hausstauballergie()

  • Pingback: useful site()

  • Pingback: water pipe leak()

  • Pingback: motorcycle accidents()

  • Pingback: www.thediabetesdestroyerreview.com()

  • Pingback: electricien saint maur des fosses()

  • Visar Uruqi

    Great Great Article, the details the style, it’s simply great. Thanks for sharing it. What about the next one on Prototypes, Constructors, and Inheritance?!

    • Thanks Visar! It’s definitely coming. Things have been so busy lately. Glad you were able to get some value from it!