ES6 Classes vs. Constructor Functions
tl;dr
- A constructor function is just a normal function that creates (constructs) an object
- JavaScript does not has classes and hence it does not has methods. What you have are properties in an object, some of which may be functions
- Javascript is not your classic class-based language but rather a prototype-based language.
- Classes in JavasScript are syntactic sugar, meaning they’re a feature that only changes how you type something, but nothing changes under the hood.
- The
class
syntax makes writing and building objects easier/neat.
'use strict'; // older version of Nodejs only allowed classes in Strcit mode
class Person {
// constructor function
constructor (firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
// adding stuff to prototype to pass on to all instances of this class
// any methods that exist in the class will be automatically added to the prototype
greet() {
return `Hello ${this.firstName} ${this.lastName}`
}
details() {
return `${this.firstName} ${this.lastName} is ${this.age} year(s) old`
}
}
let jane = new Person('Jane', 'Davis', 28)
// test
console.info(jane) // Person { firstName: 'Jane', lastName: 'Davis', age: 28 }
console.info(jane.greet) // [Function: greet]
console.info(jane.greet()) // Hello Jane Davis
console.info(jane.__proto__) // Person {}
console.info(Object.getPrototypeOf(jane)) // Person {}
// Get all methods/functions inside the class
console.info(Object.getOwnPropertyNames(Person.prototype)) // [ 'constructor', 'greet', 'details' ]
console.info(Person) // [Function: Person]
console.info(jane.constructor) // [Function: Person]
is functionally equivalent to
// constructor function
function Person(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age
}
// adding stuff to prototype to pass on to all instances of this class
Person.prototype.greet = function() {
return `Hello ${this.firstName} ${this.lastName}`
}
Person.prototype.details = function() {
return `${this.firstName} ${this.lastName} is ${this.age} year(s) old`
}
let jane = new Person('Jane', 'Davis', 28)
// test
console.info(jane) // Person { firstName: 'Jane', lastName: 'Davis', age: 28 }
console.info(jane.greet) // [Function]
console.info(jane.greet()) // Hello Jane Davis
console.info(jane.__proto__) // Person { greet: [Function], details: [Function] }
console.info(Object.getPrototypeOf(jane)) // Person { greet: [Function], details: [Function] }
console.info(Person) // [Function: Person]
Note that while jane.__proto__
in a normal constructor function gives us details for everything on the prototype Person { greet: [Function], details: [Function] }
, jane.__proto__
in a class constructor only gives the class Person {}
, not methods. Technically, there are no methods in JavaScript.
Notice that since classes are just syntactic sugar, there is no easy way of finding all (prototype) methods in a class. You can however use Object.getOwnPropertyNames(Foo.prototype)
to find all properties in a class prototype.