Adobe

decor

Web Platform Team Blog

Making the web awesome

JavaScript: Types

I like JavaScript. It is a language that is both powerful and flexible, but only if you know how to use it. Once you have mastered the JavaScript language you can build almost anything, and you can do so quickly and interactively.

If you think JavaScript is simple or primitive, then you have fallen into a trap. You will find that you have much company in this trap. The so-called JavaScript developers down there may tell you that some other language “X” is superior. They may even tell you that you would be better off with a system that transalates language X into JavaScript. To leave the trap and master JavaScript requires effort and dedication. I know, because back in 1997 I was there.

Since then I’ve learned the depth and breadth of JavaScript on my own, by studying the official specification. You can learn the complete language as well. If your title includes “JavaScript developer”, you should.

In this blog I am going to present short JavaScript program fragment and ask you to predict its output. If you are a JavaScript developer, you will find it to be child’s play. If you are still learning the language, you may have some trouble and I hope you’ll read the explanation that follows.

The following JavaScript code displays an alert box. What will the alert box contain?

 var five = 5;
five.three = 3;
alert(five + five.three);

Skip to the end of this article to learn the correct answer. Here’s an explanation of how JavaScript arrives at that answer.

There are just six types in JavaScript: Object, Number, String, Boolean, Null, and Undefined.

Objects include arrays, functions, and ordinary objects. Numbers may be integers or floating point or the special values NaN and Infinity. Strings include the empty string, "". Booleans have only two values: true and false. The last two primitive types are a little unusual: the only value whose type is Null is null, and the only value whose type is Undefined is undefined. All of the types except Object are also called “primitive”. The type of a JavaScript variable is not declared explicitly, it is inferred by the JavaScript runtime. In this case the type of the variable called five is Number because it has been assigned a Number literal.

Just like many other computer languages, JavaScript will implicitly convert the type of a value to suit the operator that is being applied to the value. Unlike many computer languages, JavaScript is very aggressive about this. For example the result of "5" - "3" is the Number 2 because the minus operator converts both of its operands to Numbers. If an operand can’t be converted to a Number, then NaN (“Not a Number”) is used instead. For example "5" - "Fred" is implicitly converted to 5 - NaN, which yields NaN.

The complete set of rules for implicit type conversions isn’t terribly complicated so long as you know what type of operands each operator requires.

The Object and String rules that follow state that initially the Object “value is converted to a primitive”. If the operand’s type must be a Number, this means that the JavaScript engine calls the object’s valueOf() method and if the result is not primitive, then the result is converted to a String with the object’s toString() method. If the operand’s type must be a String, the process begins by calling the object’s toString() method, and if its result is not primitive then the valueOf() method is applied to that. In either case, if the result still isn’t a primitive, then an exception is thrown.

If the operand’s type must be a Number but the type of the operand‘s value is:

Object:
the value is converted to a primtive and if the result is not a Number then one of the following conversions is applied
String:
the String is converted to a Number per the usual JavaScript rules
Boolean:
1 if the value is true, otherwise 0
Null:
0
Undefined:
NaN

If the operand’s type must be a String but the type of the operand’s value is:

Object:
the value is converted to a primtive and if the result is not a String then one of the following conversions is applied.
Number:
the number as a String, e.g. "123" or "12.34"
Boolean:
"true" or "false"
Null:
"null"
Undefined:
"undefined"

If the operand’s type must be a Boolean but the type of the operand’s value is:

Object:
true
Number:
false if the value is zero, otherwise true
String:
false if the value is the empty string, otherwise true
Null:
false
Undefined:
false

If the operand’s type must be an Object but the type of the operand’s value is:

Number:
the value is boxed with a Number object with new Number(value)
String:
the value is boxed with a String object with new String(value)
Boolean:
the value is boxed with a Boolean object with new Boolean(value)
Null:
an exception will be thrown
Undefined:
an exception will be thrown

Now that the type conversion rules are clear, let’s return to the example.

 var five = 5;
five.three = 3;
alert(five + five.three);

As we noted before, the first line creates a variable called five whose type is Number.

When the property accessor is applied to the variable five, its type is converted to Object. This is called “boxing” and it relies on the Number constructor, which produces an Object, not a Number primitive. The second line of the example is equivalent to this:

 (new Number(five)).three = 3;

As you can see, we have not saved a reference to the new Number Object in any variable. After this expression has been evaluated, the Number Object whose three property was set is discarded. The five variable remains unchanged.

The third line’s five.three expression causes another Number Object to be created. Since the new Object has no three property, the special undefined value is returned. The result is equivalent to this:

 alert(5 + undefined);

The addition operator converts both of its operands to Numbers. In this case undefined is converted to NaN which yields:

 alert(5 + NaN);

And that is why the Alert box in our example just displays NaN.  

19 Comments

  1. August 28, 2012 at 11:12 am, jerone said:

    The information you writing here is part of JavaScript, but is actually ECMAScript. If it where JavaScript it also consists of DOM Level, which also has Node, Element, HTMLElement and more as types.

    • August 28, 2012 at 10:05 pm, Dmitry Baranovskiy said:

      Node, Element and HTMLElement are not types, just like Array, Date and RegExp they are just objects.

  2. August 28, 2012 at 11:14 am, Marcus Pope said:

    I suppose it’s worth pointing out that this would work:


    var five = new Number(5);
    alert(five); //5
    five.three = 3;
    alert(five + five.three); //8

    I also find that it’s best to refer to numeric primitives with “number” and numeric objects with “Number” to reduce confusion on this very topic. It’s how JavaScript describes them internally as seen via the typeof operator their internal class property.

    • August 30, 2012 at 1:09 am, A C R E S T A N said:

      Yes, the article is very confusing because of the capital letter the author uses for primitives…
      ie: the sentence “the first line creates a variable called five whose type is Number” is wrong! Your code proves it.

  3. August 29, 2012 at 3:42 am, JavaScript: Types | Web Platform Team Blog « Sutoprise Avenue, A SutoCom Source said:

    [...] Types | Web Platform Team Blog Posted: August 29, 2012 in javascript 0 JavaScript: Types | Web Platform Team Blog. Share this:LinkedInTwitterDiggBloggerLike this:LikeBe the first to like [...]

  4. August 29, 2012 at 11:14 am, metadings said:

    There’s a seventh, javaScript’s most important type: the Function. In javaScript using Function you can also create new objects, so there’s also a difference in primitive types and function types.

    var Project = function () { };
    // Project instanceof Function === true
    // Project instanceof Object === true
    // (typeof Project === 'function') === true

    var o = new Project();
    // o instanceof Project === true
    // o instanceof Object === true
    // (typeof Project === 'object') === true

    Please read also my link, how I write real javaScript class functions, that are derivable without copying (like in extend or simple inheritance) and are based on a (class) function declaration and not an object declaration.

    • August 29, 2012 at 4:39 pm, Dmitry Baranovskiy said:

      Functions are obviously very important in JavaScript and deserve separate article, but they don’t have separate type. Functions are special objects. Special, but still objects.
      Objects, created by different constructors share the same type: Object. It’s easy to check: if Object(a) === a then a is Object and nothing else.

      • August 30, 2012 at 1:59 am, metadings said:

        Because of this I don’t like the typeof operator:
        it makes the difference in Function and Object and returns a string ‘function’, so it becomes confusing in that typeof says !== ‘object’.
        instanceof returns true on Function and Object, but not for primitive types like 5, that is a literal typeof ‘number’ but not a object instanceof Number.

        • October 05, 2012 at 3:32 am, Max Podriezov said:

          I was confused by typeof operator returning “object” for null….. Why ecma doesn’t want o change this to be “null”?

  5. September 02, 2012 at 4:12 am, ulu said:

    This article is a further proof that JavaScript is not just one of the most powerful, but also one of the most confusing languages in the world. Should be avoided at any cost.

    One day they’ll add support for other, more human oriented, languages to all major browsers. Hope I’ll see it in my current body.

    • September 02, 2012 at 4:38 am, Dmitry Baranovskiy said:

      When you holding a hammer, everything looks like a nail. When you think that JavaScript is confusing, everything looks like a proof. ;)

  6. September 06, 2012 at 3:26 pm, Karega said:

    This is a great article. Don’t want to get caught up in the minutia of naming practices.

  7. September 07, 2012 at 5:37 am, Dave Chapman said:

    This kind of coding error is exactly why we need better IDE’s that can syntax check code as we type and before we run it… e.g. running this throught the closure compiler produces the following warning:

    “JSC_INEXISTENT_PROPERTY: Property three never defined on Number at line 4 character 13
    alert(five + five.three);”

  8. September 07, 2012 at 6:14 am, Sponge Bob said:

    I suggest you take a look at this video: https://www.destroyallsoftware.com/talks/wat/
    Enjoy ;-)

    • October 03, 2012 at 7:37 am, Dmitry Baranovskiy said:

      If examples from the talk you suggested made you say “Wat?”, you clearly need to read my articles… and spec.

  9. September 08, 2012 at 6:25 pm, simonleung said:

    A number can be in “object” type or “number” type.
    When a condition must be a Boolean, the result may be different, e.g.
    ( Number(0) ) => true because Number(0) is an object
    ( 0 ) => false

    The type of null is “object” when using operator ‘typeof’ but (null) is false.

  10. September 30, 2012 at 4:01 am, Max Podriezov said:

    Saying that JavaScript is most confusing language is so silly – know your tool, just read the ecma-spec and you will get the power…. Dmitry described the basics, something that everybody should know before starting to code… and still someone is trying to say that we have more than 6 types))) Whats wrong with us? Why everybody think that they know how to code before reading specification? Just read the spec and i am 100% sure u will love JavaScript.

  11. November 12, 2012 at 2:26 am, Thomas said:

    (one more) Great Article!

    Its much more fun reading your posts than struggling with ECMA 262 ;)

    Well written and easy to understand!
    A good Programmer dont cry “WAT” but read the (f*) spec and try to understand whats going on…

    Thks so much for helping me expand my skills in javascript :)

    greetings from ger

    PS: And 1000^100 times sorry 4 my bad english :D

  12. November 26, 2012 at 11:38 am, Pavel Podlipensky said:

    Dmitry,

    Thanks for great js types explanation! But I’m a bit confused with the following sentence from your article:
    If the operand’s type must be a String, the process begins by calling the object’s toString() method, and if its result is not primitive then the valueOf() method is applied to that. In either case, if the result still isn’t a primitive, then an exception is thrown.

    How does engine know that operand’s type must be a String? For example if I do obj + “5” what is the expected type of obj? Looks like it should be string, right? If so, then I don’t understand why the following code execute valueOf instead of toString: http://jsfiddle.net/podlipensky/Kex6H/1/