ClassDefinesType

Misconception:

A JavaScript class definition defines a type, and instances of that class are values of that type.

Incorrect

The type of an object is equivalent to the type defined by its class definition

Correct

A class definition does not define a type; all objects have type object

Correction
Here is what's right.

In JavaScript, a class does not define a type. Objects, even those instantiated with specific constructors, are all of type object.

Types in JavaScript

There are only eight data types in JavaScript:

  • Undefined
  • Null
  • Boolean
  • String
  • Symbol (introduced in ECMAscript 6)
  • Number
  • BigInt (introduced in ECMAscript 11)
  • Object

There are no other built-in types, and there are no user-defined types. Moreover, arrays have type Object, and functions have type Object.

Determining a Type of a Value: typeof Operator

The typeof operator provides a way to (more or less) determine the type of a value:

TypeResult of typeof
Undefined"undefined"
Null"object" (!)
Boolean"boolean"
String"string"
Symbol"symbol"
Number"number"
BigInt"bigint"
Object (which does not implement [[Call]])"object" (!)
Object (which does implement [[Call]])"function" (!)

Note that typeof null returns "object", and typeof o returns "function" if o is a function, and "object" if o is any other kind of object.

Arrays are objects:

let a = [];
typeof a === 'object'; // true

Array.isArray(a); // How to test if an object is an array

While functions have the type Object, the typeof operator returns the value function:

let f = function() {};
typeof f === 'function'; // true

When the typeof operator is used on objects instantiated with different class constructors, it always return the value object.

class Square { /* ... */ }

let s = new Square();
typeof s === 'object'; // true

Determining a Class of an Object: instanceof Operator

While in JavaScript classes do not define types, it is possible to identify which constructor instantiated an object with the instanceof operator:

let s2 = new Square();
s2 instanceof Square === true;

Origin
Where could this misconception come from?

In class-based object-oriented languages, objects are instances of classes, and classes represent types. Thus, students coming from a language like Java will expect that in JavaScript, when using classes, those classes also represent types.

However, JavaScript is a prototype-based language where classes are just syntactic sugar around the ideas of prototypes and constructor functions.

Value
How can you build on this misconception?

This misconceptions provides an ideal hook for introducing the idea of prototypes and prototypical inheritance.

These ideas were originally described by Henry Lieberman in “Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems” (OOPSLA’ 86, free online, ACM).

David Ungar and Randall Smith’s Self language then demonstrated the simplicity and power of a language based on these ideas. The key paper on Self is “Self: The Power of Simplicity” (OOPSLA ‘87, ACM), and an archived version of the language is available on selflanguage.org.

JavaScript later based its own object model on these ideas. However, JavaScript is a much more complicated language which drowns out the simplicity of the ideas clearly visible in Self.

Stay up-to-date

Follow us on  twitter to hear about new misconceptions.