4
头图
"Novices of Xiaoheshan", provide front-end developers with technical information and a series of basic articles. For a better user experience, please go to our official website novices (160cafa02be9a7 https://xhs-rookies.com/ ) to learn and get the latest articles in time.

This article uses the following aspects to talk about the new keywords Class

1. Background

1.1 The origin of Class

Class was ES6 in 2015, but this keyword was first proposed in a JavaScript draft JavaScript 2.0 Classes (mozilla.org) (1999.02). At that time, because the keyword was too radical, ES4 did not change it. The class keyword in JavaScript2.0 was merged in until the ES6 draft was proposed and passed.

1.2 Reasons for adding ES6 to Class

We found the ES6 proposal GitHub TC39, and found the following explanation Stage0 stage proposal about Class

image-20201213151123623

translation:
ECMAScript already has a very complete function to define the abstraction of various things. The three characteristics of constructor, prototype, and instance are enough to achieve what classes in other languages can do. The purpose of this scarecrow (understood as a function for the time being) is not to change those semantics. On the contrary, providing a concise declarative representation for these semantics can clearly express the programmer's intention rather than the underlying imperative mechanism. Class terms, the 060cafa02becb4 keyword provides us with a way to leave the complicated prototype and call and write logically clear code.

2. How to use Class

2.1 Create a class

Use ES6 to implement the class :

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

Here we have created a class with two parameters name and dept, and a static method fun and a method getName.

2.2 Subclassing through inheritance

Use extends to implement inheritance for comparison:

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

Here we created the subclass Manager by inheriting the parent class Employee , which has one more reports attribute than the parent class, and the rest are all inherited from the parent class.

3. Horizontal and vertical comparison

The traditional OO language (java, c++, etc.) includes, for example, classes, constructors, inheritance, static methods, and so on. They use these to achieve object-oriented functions, so JavaScript do it?

3.1 Horizontal comparison between JavaScript and Java (take Java as an example)

1. Class concept ( Class ):

  • JavaScript is similar to java in that it uses class to declare a class.

2. Constructor function ( constructor ):

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

3. Subclass ( extends ):

  • JavaScript is consistent with java and both use extends to inherit.

4. Static method ( static ):

  • JavaScript in ES6 is consistent with java. Using extends to create a subclass will naturally inherit the static methods of the parent class. ES5 needs to manually declare the point.

5. The attributes of the class ( int, double, String etc.):

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

3.2 Longitudinal comparison between ES6 and ES5

We observe the following ES5 and ES6 two ways to create a parent class and a parent class. Using class create a subclass is logically clearer than the ES5 method.

First, let's compare the way to create a parent class:

image-2020.png

Then compare the subclass Manager , use extends subclasses created Manager natural inheritance which properties and methods (including static method), but ES5 in inheritance, not only to solve the problem call by call, while static methods can not be directly inherited, It needs to be declared twice in the subclass to inherit.

!image.png

But is Class really better than traditional code everywhere? In fact, it's not necessarily true. In many cases, if you just want to use the object once, why do you have to abstract the class? Is it better to use literal objects?

//字面量对象
let person = {
  name: 'Jason',
  age: 18,
  adress: 'hangzhou',
  phone: '10086',
  getPhone: function () {
    return this.phone
  },
}

4. How JavaScrpit implements Class

We all know that the method of implementing classes in ES5 is implemented through the prototype chain ( JavaScript prototype chain ). We use ES5 to implement an Employee instance:

//ES5
let employ = new Employee(1, 2)
employ.__proto__.constructor === Employee //true
employ.__proto__ === Employee.prototype //true
Employee.prototype.constructor === Employee //true

This is no problem. The __proto__ pointer points to the prototype of the constructor. Let's use ES6 class to judge again:

//ES6使用class
let employ = new Employee(1, 2)
employ.__proto__.constructor === Employee //true
employ.__proto__ === Employee.prototype //true
Employee.prototype.constructor === Employee //true

The result of both is the same! Only the object created by the function, the __proto__ pointer points to the constructor, the object created using the class keyword, and the __proto__ pointer points to the class.

Let's look at this string of code again:

console.log(typeof Employee) //function

We put the class in, and it returned function, that is, the class keyword is essentially a function, and the class created using class is still based on the function and prototype chain.

image

5. Restrictions on the Class keyword

Class is still a function in essence, what he did is to simplify the ES5 writing, which naturally brings some restrictions.

5.1 Flexibility

Assuming that there is a requirement now Manager object, as long as you use ES5 methods anywhere you only need to add a method prototype

//ES5
let manager1 = new Manager(1, 2, 3)
manager1.prototype.FunctionName = function () {
  /*写自己的逻辑*/
}

So what should I do if I class class must add this method to the class.

//ES6
class Manager extends Employee {
  constructor(name, dept, reports) {
    super(name, dept)
    this.reports = reports
  }
  FunctionName() {
    /*写自己的逻辑*/
  }
}

5.2 Class declaration cannot be promoted

Function declaration . Although the class is essentially a function, the declaration of the class cannot be promoted. That is to say, you must declare the class before you can create the object.

let a = new ES6_Practice() //报错
let b = new ES5_Practice() //成功
class ES6_Practice {}
function ES5_Practice() {}

5.3 Cannot override the class

When we want to rewrite a function method at a specific moment, we only need to redefine the method, but the class cannot be rewritten. If two identical class names appear, a syntax error ( SyntaxError ) will be reported.

class ES6_Practice{
}
class ES6_Practice{   //报错SyntaxError
    console.log("new class");
}
function ES5_Practice(){
}
function ES5_Practice(){    //没问题,重写成功
  console.log("new function");
}

6. Summary

The keyword Class ES6 is essentially made through the prototype chain and functions. Compared with the ES5 writing method, Class provides us with a more convenient and logical way to implement classes. But more flexibility and convenience will also bring some restrictions, we should also pay attention to these restrictions when writing code.

as 160cafa02bf21f TC39 on ES6 proposal :

IT's A terse and to the Provide for the Declarative Surface Those semantics Programmer that the Intent IS SO INSTEAD of Expressed at The underlying imperative Machinery hope programmer by Class keywords clearly express what they want, so that their ideas are expressed, and Not to think about the underlying mechanism.

Reference content

Stack Overflow Discussion on the Class keyword

TC39’s ES6 proposal library on GitHub

2016 ES6 Class proposal

ES6 new keyword-MDN

JavaScript2.0 draft

class private domain MDN

Java-wiki

7 design patterns in JavaScript

JavaScript in-depth from prototype to prototype chain

OO language-wiki


小和山的菜鸟们
377 声望2.1k 粉丝

每日进步的菜鸟,分享前端学习手册,和有心学习前端技术的小伙伴们互相探讨,一同成长。