SoFunction
Updated on 2025-03-01

How to implement the class in ES6 (with detailed explanation of ES5 code compiled by Babel)

Preface

This article mainly explains a question in the interview - Implementation of class grammar in ES6?

ECMAScript 6 implements class, which is a syntax sugar, making the encoding of js clearer, more humane, and more object-oriented. It also makes tools such as IDE, compile-time type checker, code style checker and other tools more convenient to detect code syntax and perform static analysis. Similarly, this gives software development engineers who have shortcomings without classes to get in touch with js.

ES5 code implementation of ES6 class

The traditional method of JavaScript language is to define and generate new objects through constructors. This writing method is quite different from the traditional object-oriented language. Therefore, ES6 introduced the concept of Class as an object template.

constructor

Effect: ES6 creates a class and adds the constructor method by default, and automatically calls the method when new is called.

ES5:

function Person(name, age) {
  = name;
  = age;
}

 = function () {
 return '(' +  + ',' +  + ')';
}
var p = new Person('Mia', 18);
(p);// Person { name: 'Mia', age: 18 }

ES6:

class Person {
 constructor(name, age) {
   = name;
   = age;
 }
 toString() {
  return '(' +  + ',' +  + ')';
 }
}
var p = new Person('Mia', 18);
(p);// Person { name: 'Mia', age: 18 }

In the ES6 class, the constructor is the constructor, which corresponds to the constructor Person in ES5, and the keyword this represents the instance object.

The class class inside can be regarded as another way of writing a constructor. It is true from typeof Person === 'function'; Person === true to true, it can be concluded that the data type of the class is a function, and the class itself points to the constructor. It can also be said that the underlying layer of class is still the function constructor.

The public methods of the class are defined on the prototype property of the class. You can use adding multiple methods to a class at once.

Special: the internally defined methods of class are non-enumerable, which is inconsistent with the behavior of ES5.

ES5:

(); // ['toString']

ES6:

(); // Person {}

The non-enumerable code implementation will be parsed after the ES6 code is transcoded with Babel.

new call

Effect: The class class must be called with new, otherwise an error will be reported.

ES5:

Person()// undefined

ES6:

Person() // TypeError: Class constructor Person cannot be invoked without 'new'

Attributes of instances

Effect: The attributes of the instance are explicitly defined on this object, otherwise they are all defined on the prototype. All instances of the class share a prototype object, consistent with ES5 behavior.

ES5:

function Person() {
  = {
  count: 0
 };
}

ES6:

class Person {
 constructor() {
   = {
   count: 0
  };
 }
}

In addition, we need to pay attention to the new proposal. Babel already supports new writing methods for instance attributes and static attributes.

Static method

A class is equivalent to an instance's prototype, and all methods defined in a class will be inherited by the instance. If you add the static keyword before a method, it means that the method will not be inherited by the instance, but will be called directly through the class, which is called "static method".

Note: If a static method contains this keyword, it refers to a class.

ES5:

function Person() { }
 = function () {
 return 'I love JavaScript.';
};
(); // I love JavaScript.

ES6:

class Person {
 static toSay() {
  return 'I love JavaScript.';
 }
}
(); // I love JavaScript.

getter and setter

ES6 provides the get and set keywords, set the value storage function and the value acquisition function for a certain attribute, intercept the access behavior of the attribute, which is consistent with the ES5 behavior.

ES5:

function Person(name) {}
 = {
 get name() {
  return 'mia';
 },
 set name(newName) {
  ('new name:' + newName);
 }
}

ES6:

class Person {
 get name() {
  return 'mia';
 }
 set name(newName) {
  ('new name:' + newName);
 }
}

The underlying implementation principle of ES6 class

The following mainly uses the babel transcoder to transcode several main methods in the class to analyze the implementation method of ES5.

How does Babel compile class

The following code is converted into ES5 code using the babel transcoder and explained in blocks according to the code structure and function.

class Person {
 constructor(name, age) {
   = name;
   = age;
 }
 toString() {
  return '(' +  + ',' +  + ')';
 }
}
var p = new Person('Mia', 18);

Running mode

"use strict";//class is enabled by default

Private functions:

JS developers underline the variable name or function name prefix, which generally means private.

The prefix and underline mean that private ownership is just a conventional habit, clarifying the intention, and no other treatment is done. Since there is no way to define private variables in the ECMAScript draft, the function or variable can still be accessed outside the function or outside the scope under this limitation.

The role of _instanceof and _classCallCheck

Check whether the declared class class is called through new, otherwise an error will be reported.

function _instanceof(left, right) {
 if (right != null && typeof Symbol !== "undefined" && right[]) {
  return right[](left);
 } else {
  return left instanceof right;
 }
}
function _classCallCheck(instance, Constructor) {
 if (!_instanceof(instance, Constructor)) {
  throw new TypeError("Cannot call a class as a function");
 }
}

The role of _createClass and _defineProperties

The _createClass function has three parameters. The Constructor is the constructor Person passed in, protoProps is the function array to be added to the prototype, and staticProps is the function to be added to the constructor itself, that is, the static method. The second and third parameters here can be defaulted and will be judged in the body of the _createClass function.

The function of the _createClass function is to collect public functions and static methods, add methods to the constructor or the prototype of the constructor, and return the constructor.

defineProperties is the main logic for adding methods to the constructor or prototype of the constructor, traversing the function array and declaring their descriptors separately. If enumerable is not defined as true, then defaults to false, and configurable is set to true. The above two boolean values ​​are to limit methods such as () to be traversed to. If value exists, add value and writable properties to the descriptor, and if it does not exist, use the get and set properties directly.

Finally, use the method to add properties to the constructor.

function _defineProperties(target, props) {
 for (var i = 0; i < ; i++) {
  var descriptor = props[i];
   =  || false;
   = true;
  if ("value" in descriptor)  = true;
  (target, , descriptor);
 }
}
function _createClass(Constructor, protoProps, staticProps) {
 if (protoProps) _defineProperties(, protoProps);
 if (staticProps) _defineProperties(Constructor, staticProps);
 return Constructor;
}

class class implementation

var Person =
 /*#__PURE__*/
 function () {
  function Person(name, age) {
   _classCallCheck(this, Person);

    = name;
    = age;
  }

  _createClass(Person, [{
   key: "toString",
   value: function toString() {
    return '(' +  + ',' +  + ')';
   }
  }]);

  return Person;
 }();

var p = new Person('Mia', 18);

Analysis:

When calling without new, this points to window, so the instance instance of Constructor is false, throwing an exception.

By calling the _createClass function, iterate over the function array. The key is the method name. If there is a value, it means there is a specific function declaration. If there is no value, it means that the get or set method is used.

Ending

After reading this, I believe everyone has a deeper understanding of the implementation of class. Recently, while I was busy with graduation design, I have sorted out the analysis of this Alibaba front-end interview question. The comment section welcomes discussion on the implementation of class. In addition, extend in class is also a very interesting implementation. In the next article, we will parse the class implementation inheritance.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.