PrototypesAreClasses
DRAFT

Misconception:

The class notation in JavaScript defines classes following the class-based object model implemented in other programming languages like Java.

Comment by Matthias
I'm not sure whether the short description and this explanation fully fit the name of this misconception. If students really think that a "prototype" is the same as a "class", then this would probably be a somewhat more focused misconception (focus on the prototype object sitting around, and how that differs from a class or even a Class object in a language like Java).
Incorrect

JavaScript is based on a class-based object model

Correct

JavaScript is based on a prototype-based object model

Correction
Here is what's right.

The class notation in JavaScript is syntactic sugar for prototypes.

In class-based object-oriented programming languages:

  • state is stored inside the instances of a class;
  • methods are defined in the class;
  • inheritance defines the structure and behavior of a class (following a parent-child subclass hierarchy).

In JavaScript:

  • both the state and methods are stored inside an object;
  • the structure, behavior and the state are all inherited (following a flat delegation hierarchy).

Any object created from a constructor adds to its own definition all the properties defined in the parent object they extend (if it is not specified, a class extends Object). Objects delegate to the parent any property they do not define (and eventually delegate it to the prototype definition).

Example:

The definition of the class Square in the first code box below is equivalent to the object constructor Square defined in the second one:

class Square {
	constructor(height, width) {
		this.height = height;
		this.width = width;
	}
}
function Square(height, width) {
	this.height = height;
	this.width = width
} 

While both examples define a constructor which can be used to create objects with equivalent properties, it is useful to label them with two different names:

  • We label a constructor defined with the class notation as class constructor;
  • We label a constructor defined without the class notation as object constructor.
Comment by Matthias
I don't think this is the official terminology. The spec uses the term "Object constructor" only to refer to the constructor function with the name `Object`. Otherwise it always uses the term "constructor" or "constructor function". In rare cases, when stressing that a function is an object, it uses "constructor function object".

We differentiate them because some of the misconceptions described in the inventory are visible only with one of the two notations.

In order to really see that classes are syntactic sugar for prototypes it is possible to use the operator typeof:

class Square { /* ... */ }

typeof Square === 'function' // true

The class Square has type "function" (because of its constructor).

Origin
Where could this misconception come from?

Comment by Matthias
With "Origin" I didn't mean "origin of the language feature", but "where might students get this misconception from". We probably should improve the subtitle of the Origin section to make that clear.

In old versions of JavaScript (before ECMAscript 6), the class notation did not exist and it was possible to create an object constructor only with the definition of a function and its prototype:

function Square(height, width) {
  /* ... */
}
Square.prototype.compare = function(a,b) {/* ... */}

With the introduction of the class notation, the complexity of prototypes are now hidden behind the abstraction introduced by the new notation.

Classes were introduced in JavaScript specifically to mimic the class keyword used in other programming languages, and to appeal to developers used to class-based object-oriented programming.

Stay up-to-date

Follow us on  twitter to hear about new misconceptions.