JavaScript’s type system
This blog post examines JavaScript‘s type system. It answers questions such as: Is JavaScript dynamically typed? Weakly typed? What is coercion?
JavaScript, as specified via the ECMAScript language specification, only has 6 types. Quoting Chap. 8:
That has interesting consequences for constructors. Technically, they don’t introduce new types, even though they are said to have instances.
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”.
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.
The static type of foo is Object, the dynamic type of foo is String.
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.
Mostly, however, things silently fail or work. For example, if you access a property that does not exist, you get the value undefined:
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:
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.
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.
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.
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.
Comments
Post a Comment