JavaScript’s type system

[2013-09-01] dev, javascript, jslang
(Ad, please don’t block)
This blog post examines JavaScript‘s type system. It answers questions such as: Is JavaScript dynamically typed? Weakly typed? What is coercion?

JavaScript’s types

JavaScript, as specified via the ECMAScript language specification, only has 6 types. Quoting Chap. 8:
An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are
  • Undefined,
  • Null,
  • Boolean,
  • String,
  • Number, and
  • Object.
That has interesting consequences for constructors. Technically, they don’t introduce new types, even though they are said to have instances.

Static versus dynamic

In the context of language semantics and type systems, “static” usually means “at compile time” or “without running a program”, while “dynamic” means “at runtime”.

Static typing versus dynamic typing

In a statically typed language, variables, parameters and members of objects (JavaScript calls them properties) have types that the compiler knows at compile time. The compiler can use that information to perform type checks and to optimize the compiled code.

Even in statically typed languages, a variable (etc.) also has a dynamic type, the type of the variable’s value at a given time at runtime. The dynamic type can differ from the static type. For example (Java):

    Object foo = "abc";
The static type of foo is Object, the dynamic type of foo is String.

JavaScript is dynamically typed, types of variables are generally not known at compile time.

Static type checking versus dynamic type checking

If you have type information, you can check whether a value that is transported to another location (via a function call, an assignment, etc.) has the correct type. Statically type-checked languages perform this kind of check at compile time, dynamically type-checked languages at runtime. A language can be both statically type-checked and dynamically type-checked. If a check fails, you usually get some kind of error or exception.

JavaScript performs a very limited kind of dynamic type checking,

    > var foo = null;
    > foo.prop
    TypeError: Cannot read property 'prop' of null
Mostly, however, things silently fail or work. For example, if you access a property that does not exist, you get the value undefined:
    > var bar = {};
    > bar.prop
    undefined

Coercion

In JavaScript, the main way of dealing with a value whose type doesn’t fit is to coerce it to the correct type. Coercion means implicit type conversion. Most operands coerce:
    > '3' * '4'
    12
JavaScript has internal functions for performing this kind of conversion explicitly [1]. Some of them can be accessed in the language, via the functions Boolean, Number, String, Object.
    > Number(true)
    1
    > Number('123')
    123
    > String(true)
    'true'
JavaScript’s built-in conversion mechanisms only work for the types Boolean, Number, String and Object. There is no standard way for converting an instance of one constructor to an instance of another constructor.

Don’t use: strongly typed, weakly typed

The terms “strongly typed” and “weakly typed” do not have generally useful definitions. People use them, but it would be better to use other terms such as statically typed, statically type-checked, etc.

Reference

  1. Categorizing values in JavaScript