“The Newbies of Little Wo Shan” provides front-end developers with technical information and a series of basic articles. For a better user experience, please go to xhs-rookies.com/ to learn the latest articles.

This article will talk about the new keyword Class in ES6 through the following aspects

  • background
  • How to use Class
  • Horizontal and vertical comparison
  • How does JavaScript implement Class
  • Restrictions on the Class keyword
  • conclusion

1. The background

1.1 History of Class

Class was officially introduced in ES6 in 2015, but the keyword was first introduced in a draft of JavaScript called JavaScript 2.0 Classes (mozilla.org) (1999.02) because it was too radical, As a result, the class keyword in JavaScript2.0 is not incorporated in ES4 until the draft of ES6 is proposed and approved.

1.2 Reasons why ES6 Joins the Class

We found the ES6 proposal on GitHub of TC39 and the following explanation in the Stage0 proposal on Class:

Translation:

ECMAScript already has very comprehensive capabilities to define abstractions of various things. The three features of constructors, prototypes, and instances are enough to do what classes in other languages can do. The purpose of this scarecrow (tentatively understood as a feature) is not to change those semantics. Instead, providing a concise declarative representation of these semantics clearly expresses the programmer’s intent rather than the underlying imperative mechanism. In layman’s terms, the Class keyword gives us a way to write logical code without all the clunky prototype and call.

2. How to use Class

2.1 create the class

Use Class in ES6 to implement classes:

//ES6
class Employee {
  constructor(name, dept) {
    this.name = name
    this.dept = dept
  }
  static fun() {
    console.log('static')}getName() {
    console.log(this.name)
  }
}
Copy the code

Here we create a class that takes name and dept and has a static method fun and a method getName.

2.2 Implement subclasses by inheritance

Use extends to implement inheritance for comparison:

//ES6
class Manager extends Employee {
  constructor(name, dept, reports) {
    super(name, dept)
    this.reports = reports
  }
}
Copy the code

Here we subclass Manager by inheriting from the parent class Employee, with one more reports attribute and all the rest from the parent class.

3. Horizontal and vertical comparison

Traditional OO languages (Java, c++, and so on) have classes, constructors, inheritance, static methods, and so on. They use this to implement object-oriented functionality, so how does JavaScript do that?

3.1 Horizontal comparison of JavaScript and Java (toJavaAs an example)

1. Concept of class (Class) :

  • JavaScript, like Java, uses class to declare a class.

2. Constructor (constructor) :

  • JavaScript uses the constructor method as a constructor, while Java uses the class name as a constructor.

3. The subclass (extends) :

  • JavaScript, like Java, uses extends to inherit.

4. Static method (static) :

  • JavaScript in ES6 is similar to Java in that using extends to create a subclass naturally inherits the static methods of the parent class. ES5 requires manual declaration of pointing.

5. Class attributes (Int, double, StringEtc.) :

  • JavaScript benefits from automatic type inference and does not need to declare the attributes of the class to be displayed.

3.2 Vertical comparison of ES6 and ES5

Using class to create subclasses is logically clearer than using ES5.

First let’s compare the way the parent class is created:

Using the extends extension extension, Manager naturally inherits properties and methods (including static methods), but ES5 requires that static methods not be directly inherited by call, and that static methods cannot be directly inherited by a second declaration in the subclass.

!

But is Class really better than traditional code everywhere? Not really. In many cases, if you just want to use the object once, why abstract the class? Wouldn’t it be better to use literal objects?

// A literal object
let person = {
  name: 'Jason'.age: 18.adress: 'hangzhou'.phone: '10086'.getPhone: function () {
    return this.phone
  },
}
Copy the code

4. How does JavaScrpit implement Class

We all know that ES5 implements a class through a prototype chain. We use ES5 notation to implement an instance of Employee:

//ES5
let employ = new Employee(1.2)
employ.__proto__.constructor === Employee //true
employ.__proto__ === Employee.prototype //true
Employee.prototype.constructor === Employee //true
Copy the code

The __proto__ pointer points to the constructor’s prototype, and we’ll use ES6’s class to check again:

/ / ES6 in class
let employ = new Employee(1.2)
employ.__proto__.constructor === Employee //true
employ.__proto__ === Employee.prototype //true
Employee.prototype.constructor === Employee //true
Copy the code

The result is the same! Only for objects created using functions, the __proto__ pointer points to constructors, and for objects created using the class keyword, the __proto__ pointer points to classes.

Let’s look at this code again:

console.log(typeof Employee) //function
Copy the code

When we put class in, we actually return function, so the class keyword is essentially a function, and the class created using class is still based on a chain of functions and prototypes.

5. Restrictions on the Class keyword

Since Class is still essentially a function, and what it does is simplify the way ES5 is written, there are naturally some limitations.

5.1 flexibility

Suppose you now have a requirement to add a method to a Manager object, anywhere using ES5 methods just add the method to Prototype

//ES5
let manager1 = new Manager(1.2.3)
manager1.prototype.FunctionName = function () {
  /* Write your own logic */
}
Copy the code

So what do you do with class? Class must include the method in the class.

//ES6
class Manager extends Employee {
  constructor(name, dept, reports) {
    super(name, dept)
    this.reports = reports
  }
  FunctionName() {
    /* Write your own logic */}}Copy the code

5.2 Class declaration cannot be promoted

Function declarations are promotable. Although a class is essentially a function, the declaration of a class is not promotable, meaning that you must declare the class before you can create an object.

let a = new ES6_Practice() / / an error
let b = new ES5_Practice() / / success
class ES6_Practice {}
function ES5_Practice() {}
Copy the code

5.3 Classes cannot be overridden

When we want to rewrite a function method at a particular moment, we just need to redefine the method, but the class cannot be overridden. If two identical class names appear, a SyntaxError will be reported.

class ES6_Practice{}class ES6_Practice{   / / error SyntaxError
	console.log("new class");
}
function ES5_Practice(){}function ES5_Practice(){	// No problem, rewrite successfully
  console.log("new function");
}
Copy the code

6. Summary

The ES6 keyword Class is essentially a prototype chain and a function. Class provides a more convenient and logical way to implement classes than using ES5. But being more flexible and convenient also comes with limitations that we need to be aware of when writing code.

As TC39 said in ES6 proposal:

It’s to provide a terse and declarative surface for those semantics so that programmer intent is expressed instead of The underlying imperative Machinery wants programmers to use the Class keyword to clearly express what they want, allowing them to express their ideas without having to think about the underlying mechanism.

Refer to the content

Stack Overflow discussion on the Class keyword

TC39’s ES6 proposal library on GitHub

2016 ES6 proposal on Class

The keyword -mDN is added in ES6

The draft JavaScript2.0

Class private domain MDN

Java-wiki

7 design patterns in JavaScript

JavaScript goes from prototype to prototype chain

OO language – wiki