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

Introduction to version management tool Rational ClearCase

Rational ClearCase is a software configuration ma...

What are Web Slices?

IE8 new feature Web Slices (Web Slices) Microsoft...

Essential Handbook for Web Design 216 Web Safe Colors

The color presentation on a web page will be affec...

onfocus="this.blur()" is hated by blind webmasters

When talking about the screen reading software op...

Detailed explanation of Shell script control docker container startup order

1. Problems encountered In the process of distrib...

WeChat Mini Program User Authorization Best Practices Guide

Preface When developing WeChat applets, you often...

The process of building lamp architecture through docker container

Table of contents 1. Pull the centos image 2. Bui...

vue3.0+echarts realizes three-dimensional column chart

Preface: Vue3.0 implements echarts three-dimensio...

Example of how to reference environment variables in Docker Compose

In a project, you often need to use environment v...

Detailed explanation of the usage of MySQL data type DECIMAL

MySQL DECIMAL data type is used to store exact nu...

Detailed explanation of js event delegation

1. Each function is an object and occupies memory...

Things to note when writing self-closing XHTML tags

The img tag in XHTML should be written like this:...

vue3 timestamp conversion (without using filters)

When vue2 converts timestamps, it generally uses ...

JavaScript Closures Explained

Table of contents 1. What is a closure? 2. The ro...