js learning notes: class, super and extends keywords

js learning notes: class, super and extends keywords

Preface

JavaScript language introduced the keyword class in ES6. During the study interview, you will often be asked by the interviewer to talk about your understanding of class in ES6, as well as how to use this keyword in our code and what to pay attention to when using this keyword. This article will summarize the relevant knowledge points.

text

1. Create objects before es6

Let's first look at the fact that before es6, if we wanted to create an object, we could only create it through the constructor function, adding the static method to the prototype so that each instance could call the method.

function Person(name, age) {
            this.name = name
            this.age = age
            Person.prototype.sayHello = function () {
                return "hello," + this.name + ",good morning"
            }
        }
        let person = new Person("serendipity", 18)
        console.log(person.sayHello())//hello, serendipity, good morningconsole.log(person instanceof Person);//true
        console.log(person instanceof Object);//true

2. Class declaration after es6

Classes are templates for creating objects; they encapsulate data with code to manipulate that data. Classes in js are built on top of prototypes, but also share some syntax and semantics similar to ES5 classes.

In fact, a class is a special kind of function. Just like defining function declarations and function expressions, the class syntax also consists of two parts: class declaration and class expression.

class Person {
            constructor(name, age) { //Own property, this property appears on the instance and can only be created in the class constructor or method this.name = name
                this.age = age
            }
            sayHello() {//Equivalent to Perosn.prototype.sayHello
                return `hello,${this.name},Good morning`
            }
        }
        let person = new Person("serendipity", 18)
        console.log(person.sayHello()); //hello, serendipity, good morning console.log(person instanceof Person); //true
        console.log(person instanceof Object);//true
        console.log(typeof Person);//function
        console.log(typeof Person.prototype.sayHello);//function

The class declaration allows you to define a constructor using the constructor method in the class without having to define a special construction method to use as a constructor.

The syntax of a class is similar to that of a normal function before ES5, but there are some features to note:

(1) Class declarations will not be hoisted. Class declaration behavior is similar to let, so there will be a temporary dead zone in the class during execution.

(2) All code in the class automatically runs in strict mode, and strict mode cannot be exited

(3) All methods in a class are non-enumerable. Ordinary custom methods can only be defined as non-enumerable through object.defineProperty()

(4) None of the methods in the class have [[construct]] inside, so calling them with new will throw an error

(5) Calling a class constructor without using new will throw an error

(6) Attempting to override the class name inside a class method will throw an error

Convert the above code to ES5 as follows:

let PersonClass = (function () {
            "use strict"
            const PersonClass = function (name, age) {
                // Determine whether the constructor is called by new if (typeof new.target === "undefined") {
                    throw new Error("Constructor must be called with new.")
                }
                this.name = name
                this.age = age
            }
            Object.defineProperty(PersonClass.prototype, "sayHello", {
                value: function () {
                    if (typeof new.target !== "undefined") { // Ensure that new is not used when calling
                        throw new Error("Method cannot be called with new.")
                    }
                    return "hello," + this.name + ",Good morning!"
                },
                enumerable: false,
                configurable: true,
                writable: true
            })
            return PersonClass
        })()
        var personClass = new PersonClass("serendipity", 18)
        console.log(personClass.name);//serendipity
        console.log(personClass.sayHello()); ///hello, serendipity, good morning!

Two PersonClass declarations, one let declaration in the outer scope, and another const declaration inside the immediately executed function, are why class methods cannot override the class name, while code outside the class is allowed. At the same time, only the class name inside the class is considered to be declared as const, which means that you can rewrite the class name externally (equivalent to let), but you cannot do so inside the class method.

3. Class inheritance

The inheritance method before ES6 mainly implements inheritance through a combination of constructors and prototype chains. The specific code is as follows:

function Rectangle(length, width) {
            this.length = length
            this.width = width
            Rectangle.prototype.getArea = function () {
                return this.length * this.width
            }
        }
        function Square(length) {
            Rectangle.call(this, length, length)
        }
        Square.prototype = Object.create(Rectangle.prototype, {
            constructor: {
                value: Square,
                enumerable: true,
                writeable: true,
                configurable: true
            }
        })
        var square = new Square(3)
        console.log(square.getArea()); //9
        console.log(square instanceof Square); //true
        console.log(square instanceof Rectangle); //true

The above code implements the Rectangle parent class by adding static methods to the constructor and prototype. Then the subclass Square calls the parent class constructor through Rectangle.call(this, length, length). Object.create will create an empty object internally to connect the two prototype objects, and then manually point the constructor to itself. This method of implementing inheritance code is complicated and difficult to understand, so the creation of ES6 class makes inheritance simpler. Use the extends keyword to specify the parent class that the current class needs to inherit. The prototype of the generated class will be automatically adjusted, and you can also use the super() method to access the constructor of the base class. The specific code is as follows:

class Rectangle {
            constructor(length, width) {
                this.length = length
                this.width = width
            }
            getArea() {
                return this.length * this.width
            }
        }
        class Square extends Rectangle {
            constructor(length) {
                super(length, length)
            }
            getArea() {
                return this.length + this.length
            }

        }
        var square = new Square(3)
        console.log(square.getArea()); //6
        console.log(square instanceof Square); //true
        console.log(square instanceof Rectangle); //true

In the above code, the Square class overrides the getArea() method of the base class. When the function name in the derived subclass is the same as the function name in the base class, the method of the derived class will mask the method of the base class. At the same time, the base class method can also be called in the subclass getArea () { return super.getArea() } to expand it.

4. Inheriting static members of the class

Static members: additional methods added directly to the constructor. For example, methods added to prototypes in ES5 are static members. The introduction of ES6 class simplifies the creation of static members. You only need to add the static keyword before the names of methods and accessor properties. For example, the following code is used to distinguish between static methods and instance methods.

function PersonType(name) {
        this.name = name;
    }
    // static method PersonType.create = function(name) {
        return new PersonType(name);
    };
    // Instance method PersonType.prototype.sayName = function() {
        console.log(this.name);
    }; var person = PersonType.create("Nicholas");

To use static members in ES6:

class Rectangle {
            constructor(length,width) {
                this.length = length
                this.width = width
            }
            getArea() {
                return this.length * this.width
            }
            static create(length,width) {
                return new Rectangle(length, width)
            }
        }
        class Square extends Rectangle {
            constructor (length){
                super(length,length)
            }
        }
        var square = Square.create(3,4)
        console.log(square.getArea()); //12
        console.log(square instanceof Square); //false
        console.log(square instanceof Rectangle); //true

In the above code, a new static method create() is added to the Rectangle class, which exists as Square.create() through inheritance and behaves in the same way as Rectangle.create(). Note that static members cannot be accessed through instances, and you always need to call the class itself directly to access them.

Final Thoughts

The above is the full content of this article. I hope it will bring some help and progress to the readers. If it is convenient, please follow me. Xiaobai’s Growth Path will continue to update some common problems and technical points in work.

You may also be interested in:
  • JavaScript object-oriented class inheritance case explanation
  • JS quickly master ES6 class usage
  • Two ways to write JS tab plugins (jQuery and class)
  • Detailed explanation of adding and deleting class names using JS
  • Class in front-end JavaScript

<<:  Differences between Windows Server win2003, win2008R2, win2012, win2016, and win2019 system versions

>>:  How to install MySQL 8.0.17 and configure remote access

Recommend

In-depth study of vue2.x--Explanation of the h function

Table of contents Solution, Summarize: vue projec...

How to move mysql5.7.19 data storage location in Centos7

Scenario: As the amount of data increases, the di...

The difference between ${param} and #{param} in MySQL

The parameter passed by ${param} will be treated ...

JavaScript implements draggable progress bar

This article shares the specific code of JavaScri...

Detailed explanation of Linux one-line command to process batch files

Preface The best method may not be the one you ca...

Vue conditional rendering v-if and v-show

Table of contents 1. v-if 2. Use v-if on <temp...

The whole process of installing and configuring Harbor1.7 on CentOS7.5

1. Download the required packages wget -P /usr/lo...

This article will show you how to use SQL CASE WHEN in detail

Table of contents Simple CASEWHEN function: This ...

Summary of new usage of vi (vim) under Linux

I have used the vi editor for several years, but ...

MySQL 8.0.16 installation and configuration graphic tutorial under macOS

This article shares the installation and configur...

Docker connection mongodb implementation process and code examples

After the container is started Log in to admin fi...

Analysis of the Neglected DOCTYPE Description

doctype is one of them: <!DOCTYPE HTML PUBLIC &...

TypeScript namespace merging explained

Table of contents Merge namespaces with the same ...

Detailed explanation of JavaScript error capture

Table of contents 1. Basic usage and logic 2. Fea...