What are the differences between JavaScript ES2015 classes and ES5 function constructors?
TL;DR
ES2015 introduces a new way of creating classes, which provides a more intuitive and concise way to define and work with objects and inheritance compared to the ES5 function constructor syntax. Here's an example of each:
// ES5 function constructorfunction Person(name) {this.name = name;}// ES2015 Classclass Person {constructor(name) {this.name = name;}}
For simple constructors, they look pretty similar. The main difference in the constructor comes when using inheritance. If we want to create a Student
class that subclasses Person
and add a studentId
field, this is what we have to do in addition to the above.
// ES5 function constructorfunction Student(name, studentId) {// Call constructor of superclass to initialize superclass-derived members.Person.call(this, name);// Initialize subclass's own members.this.studentId = studentId;}Student.prototype = Object.create(Person.prototype);Student.prototype.constructor = Student;// ES2015 Classclass Student extends Person {constructor(name, studentId) {super(name);this.studentId = studentId;}}
It's much more verbose to use inheritance in ES5 and the ES2015 version is easier to understand and remember.
Comparison of ES5 function constructors vs ES2015 classes
Feature | ES5 Function Constructor | ES2015 Class |
---|---|---|
Syntax | Uses function constructors and prototypes | Uses class keyword |
Constructor | Function with properties assigned using this | constructor method inside the class |
Method Definition | Defined on the prototype | Defined inside the class body |
Static Methods | Added directly to the constructor function | Defined using the static keyword |
Inheritance | Uses Object.create() and manually sets prototype chain | Uses extends keyword and super function |
Readability | Less intuitive and more verbose | More concise and intuitive |
ES5 function constructor vs ES2015 classes
ES5 function constructors and ES2015 classes are two different ways of defining classes in JavaScript. They both serve the same purpose, but they have different syntax and behavior.
ES5 function constructors
In ES5, you define a class-like structure using a function constructor and prototypes. Here's an example:
// ES5 function constructorfunction Person(name, age) {this.name = name;this.age = age;}Person.prototype.greet = function () {console.log('Hello, my name is ' + this.name + ' and I am ' + this.age + ' years old.',);};// Creating an instancevar person1 = new Person('John', 30);person1.greet(); // Hello, my name is John and I am 30 years old.
ES2015 classes
ES2015 introduced the class
syntax, which simplifies the definition of classes and supports more features such as static methods and subclassing. Here's the same example using ES2015:
// ES2015 Classclass Person {constructor(name, age) {this.name = name;this.age = age;}greet() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`,);}}// Creating an instanceconst person1 = new Person('John', 30);person1.greet(); // Hello, my name is John and I am 30 years old.
Key Differences
-
Syntax and Readability:
- ES5: Uses function constructors and prototypes, which can be less intuitive and harder to read.
- ES2015: Uses the
class
keyword, making the code more concise and easier to understand.
-
Static Methods:
- ES5: Static methods are added directly to the constructor function.
- ES2015: Static methods are defined within the class using the
static
keyword.
// ES5function Person(name, age) {this.name = name;this.age = age;}Person.sayHi = function () {console.log('Hi!');};Person.sayHi(); // Hi!// ES2015class Person {static sayHi() {console.log('Hi!');}}Person.sayHi(); // Hi! -
Inheritance
- ES5: Inheritance is achieved using
Object.create()
and manually setting the prototype chain. - ES2015: Inheritance is much simpler and more intuitive with the extends keyword.
// ES5 Inheritance// ES5 function constructorfunction Person(name, age) {this.name = name;this.age = age;}Person.prototype.greet = function () {console.log('Hello, my name is ' +this.name +' and I am ' +this.age +' years old.',);};function Student(name, age, grade) {Person.call(this, name, age);this.grade = grade;}Student.prototype = Object.create(Person.prototype);Student.prototype.constructor = Student;Student.prototype.study = function () {console.log(this.name + ' is studying.');};var student1 = new Student('Alice', 20, 'A');student1.greet(); // Hello, my name is Alice and I am 20 years old.student1.study(); // Alice is studying.// ES2015 Inheritance// ES2015 Classclass Person {constructor(name, age) {this.name = name;this.age = age;}greet() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`,);}}class Student extends Person {constructor(name, age, grade) {super(name, age);this.grade = grade;}study() {console.log(`${this.name} is studying.`);}}const student1 = new Student('Alice', 20, 'A');student1.greet(); // Hello, my name is Alice and I am 20 years old.student1.study(); // Alice is studying. - ES5: Inheritance is achieved using
-
super
calls:- ES5: Manually call the parent constructor function.
- ES2015: Use the
super
keyword to call the parent class's constructor and methods.
Conclusion
While both ES5 and ES2015 approaches can achieve the same functionality, ES2015 classes provide a clearer and more concise way to define and work with object-oriented constructs in JavaScript, which makes the code easier to write, read, and maintain. If you are working with modern JavaScript, it is generally recommended to use ES2015 classes over ES5 function constructors.