class keyword in ES6

Posted by rgpayne on Wed, 26 Jan 2022 05:49:05 +0100

Welcome to my blog https://qqqww.com/ , I wish our fellow countrymen of the yard farmers to reach the peak of their lives and marry Bai Fumei as soon as possible~~~

Statement: This article refers to Mr. Ruan Yifeng, the leader of the industry Introduction to ES6 standards

catalog:

  1. Object oriented in ES5
  2. class keyword in ES6
  3. Instance of class
  4. Value taking function (getter) and stored value function (setter)
    Class inheritance
  5. Some points needing attention
  6. There is no variable promotion
  7. name
  8. Generator
  9. this
  10. Static method
  11. Static properties
  12. Private method
  13. Private property
  14. Class inheritance
    1. extends
    2. super

Object oriented in ES5

// Create a constructor
function People (name, age) {
    this.name = name
    this.age = age
}

// Add a say method to the prototype object of the constructor
People.prototype.say = function () {
    return 'hello everyone'
}

// Instantiate the People constructor and save it in variable a
var a = new People('zhangsan', 10)

class keyword in ES6

Use the class class in ES6 to rewrite the above example

class People {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    say() {
       return 'hello everyone' 
    }
}

The two example is as like as two peas. The actual function is the same. You can see that there is a constructor method, which is the construction method, while the this keyword represents the instance object, and the method does not need comma separation, and adds error.

The class class of ES6 can be regarded as another way to write the constructor. The proof is as follows:

class People {  }
typeof People // "function"
People.prototype.constructor === People // true

Instance of class

Similarly, use the new keyword

class People {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    say() {
       return 'hello everyone' 
    }
}
var people = new People('zhangsan', 18)

Like ES5, the attributes of an instance are defined on the prototype (that is, on the class) unless they are explicitly defined on the instance itself (that is, on the this object)

All instances of the class share a prototype object

class People {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    say() {
       return 'hello everyone' 
    }
}
var people1 = new People('zhangsan', 18)
var people2 = new People('zhaosi', 20)
people1._proto_ === people2._proto // true

This means that you can use the__ proto__ Property to add a method to the class

class People {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    say() {
       return 'hello everyone' 
    }
}
var people1 = new People('zhangsan', 18)
var people2 = new People('zhaosi', 20)
people1._proto_.eat = function () {
    return 'banner'
}
people1.eat() // 'banner'
people2.eat() // 'banner'

Value taking function (getter) and stored value function (setter)

The case is based on Ms. Ruan Yifeng's introduction to ES6 standard

class CustomHTMLElement {
    constructor(element) {
      this.element = element;
  }

  get html() {
      return this.element.innerHTML;
  }

  set html(value) {
      this.element.innerHTML = value;
  }
}

var descriptor = Object.getOwnPropertyDescriptor(
    CustomHTMLElement.prototype, "html"
);

"get" in descriptor  // true
"set" in descriptor  // true

The stored value function and value function are defined on the description object of html attribute, which is completely consistent with ES5

Some points needing attention

There is no variable promotion

Class does not have variable promotion

new Foo(); // ReferenceError
class Foo {}

For the above code, if Foo is defined after and used before, an error will be reported

name

In essence, the Class of ES6 is only a layer of wrapper of the constructor of ES5, so many features of the function are inherited by Class, including the name attribute

class People {}
People.name // "People"

The name attribute always returns the class name immediately following the class keyword

Generator method

If a method is preceded by an asterisk (*), it means that the method is a Generator function

The generator can be returned many times during execution, so it looks like a function that can remember the execution state. Using this, writing a generator can realize the functions that can be realized only by object-oriented. Please move to Mr. Liao Xuefeng's for details generator

class Foo {
  constructor(...args) {
    this.args = args;
  }
  * [Symbol.iterator]() {
    for (let arg of this.args) {
      yield arg;
    }
  }
}

for (let x of new Foo('hello', 'world')) {
  console.log(x);
}
// hello
// world

In the above code, the symbol of Foo class The iterator method is preceded by an asterisk, indicating that the method is a Generator function. Symbol. The iterator method returns a default iterator of the Foo class, for The of loop will automatically call the iterator and return multiple times, printing out one parameter at a time until all parameters are traversed

this

If this is contained in the method of the class, it points to the instance of the class by default. However, you must be very careful. Once this method is used alone, it is likely to report an error

class People {
    getPeople(name = 'zhangsan') {
        this.print(`hello ${ name }`)
    }
    print(text) {
        console.log(text)
    }
}
const people = new People()
const { getPeople } = people
getPeople() // TypeError: Cannot read property 'print' of undefined

Solution 1: bind this in the constructor

class People {
    constructor() {
        this.getPeople = this.getPeople.bind(this)
    }
    getPeople(name = 'zhangsan') {
        this.print(`hello ${ name }`)
    }
    print(text) {
        console.log(text)
    }
}
const people = new People()
const { getPeople } = people
getPeople() // 'hello zhangsan'

Solution 2: use the arrow function

class People {
    constructor() {
        this.getPeople = (name = 'zhangsan') => this.print(`hello ${ name }`)
    }
    print(text) {
        console.log(text)
    }
}
const people = new People()
const { getPeople } = people
getPeople() // 'hello zhangsan'

Static method

Static keyword. Methods with static keyword will not be inherited, and instances cannot be called. They must be called directly through classes

class People {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    static say() {
       console.log('say everyone')
    }
}
People.say() // 'hello everyone' 
var people = new People
people.say() // TypeError: people.say is not a function

Note that if the static method contains the this keyword, this refers to the class, not the instance

class People {
    static hello() {
        this.say()
    }
    static say() {
        console.log('I'm static')
    }
    say() {
        console.log('I am non static')
    }
}
People.hello() // I'm static

Static properties

Add the static keyword before the attribute to define the static attribute

class Foo {
  static prop = 1;
}

Private method

Private method is a common requirement, but ES6 does not provide it. It can only be simulated through alternative methods

Method 1: make a distinction in naming

class People {
    // public Method 
    foo (name) {
        this._getName(name)  
    }
    
    // Private method
    _getName(name) {
        return this.peop = name
    }
}

In the above code, the underscore in front of the getName method indicates that it is a private method limited to internal use. However, this naming is not safe. You can still call this method outside the class

Method 2: remove the private method from the module

class People {
    // public Method 
    foo (name) {
        getName.call(this, name)  
    }
}
// Private method
getName(name) {
    return this.peop = name
}

In the above code, call is used to make this, that is, foo call the getName method, which makes getName actually become the private method of the current module

Private property

Please refer to http://es6.ruanyifeng.com/#docs/class

Class inheritance

Class can inherit through the extends keyword. Let's take a look at an example first

extends

// This is the parent class
class Person {
  constructor(name, age){
    this.name = name
    this.age = age
  }
}

// These are some properties and methods that the subclass can inherit from the parent class
class American extends Person {
}
const a1 = new American('Jack', 20)
console.log(a1.name) // Jack

// This is a subclass. Chinese people can inherit some properties and methods of the parent class
class Chinese extends Person{
}

const c1 = new Chinese('Zhang San', 22)
console.log(c1.name) // Zhang San

super

It can be used either as a function or as an object. In these two cases, its usage is completely different

Case 1: when super is called as a function, it represents the constructor of the parent class. ES6 requires that the constructor of a subclass must execute the super function once

// This is the parent class
class Person {
  constructor(name, age){
    this.name = name
    this.age = age
  }

  // Example method of greeting
  sayHello(){
    console.log('hello everyone')
  }
}

// This is a subclass of Americans 
class American extends Person {
  constructor(name, age){
    super(name, age)
  }
}

const a1 = new American('Jack', 20)
console.log(a1)
a1.sayHello()


// This is a subclass of Chinese
class Chinese extends Person{
  // Name name 
  // Age age
  // IDNumber ID number is Chinese unique, and since it is unique, it is not suitable for mounting to the parent class.
  constructor(name, age, IDNumber){
    super(name, age)
    this.IDNumber = IDNumber
  }
}

const c1 = new Chinese('Zhang San', 22, '130428******')
console.log(c1)
c1.sayHello()

be careful:

  1. If you need to add your own unique attribute, it cannot be attached to the parent class
  2. In subclasses, this can only be used after super

Case 2: when super is used as an object, in the normal method, it points to the prototype object of the parent class; In a static method, point to the parent class

// This is the parent class
class Person {
  constructor(name, age){
    this.name = name
    this.age = age
  }

  // Example method of greeting
  sayHello(){
    console.log('hello everyone')
  }
}

// This is a subclass of Americans 
class American extends Person {
  constructor(name, age){
    super(name, age)
    console.log(super.sayHello())
  }
}

let amer = new American()

In the above code, super in the subclass American Sayhello() is to use super as an object. At this time, super in the normal method points to person Prototype, so super Sayhello () is equivalent to person prototype. sayHello().



Author: foreman Wang
Link: https://www.jianshu.com/p/a7e5fcb8a67f
Source: Jianshu
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.