This is the 19th day of my participation in the August Wenwen Challenge.More challenges in August

preface

Last time we covered some basic things, such as what is inheritance, the retrieval rules of prototype chain, and gave two examples of inheritance

Object-oriented – Inheritance (PART 1)

Today we’re going to continue with examples, code and diagrams, and then we’re going to do a little summary.

Inheritance – Prototype chain inheritance -2

So let’s take care of the problem we left over from yesterday.

Problem: Can’t access object properties of the parent class?

In other words, how do you have instance properties and stereotype properties of a parent class?

Solution: Construct an instance of the parent class and set it as a prototype object for the subclass

    <script>
        /** * the Person * constructor@constructor* /
        function Person() {
            this.name = 'Jack';
            this.lore = ['html'.'css'];
        }

        Person.prototype.run = function () {
            console.log('run');
        };


        /** * the Student * constructor@constructor* /
        function Student() {
            this.num = 'Tom';
        }

        // 1. Construct an instance of the parent class
        var p = new Person();
        // 2. And set it to the prototype object of the subclass
        Student.prototype = p;

        var stu = new Student();
        console.log(stu); // Student {num: "Tom"}

        console.log(stu.num); // Tom
        stu.run(); / / run
        console.log(stu.name); // Jack
        console.log(stu.lore); // ["html", "css"]

        console.log(stu.constructor.name); // Person
    </script>
Copy the code

The illustration

Problem: Type problem

Inheritance – Prototype chain inheritance -3

Fix the problem: Just fix the constructor pointer

    <script>
        /** * the Person * constructor@constructor* /
        function Person() {
           this.name = 'Jack';
           this.lore = ['html'.'css'];
        }
    
        Person.prototype.run = function () {
            console.log('run');
        };
    
    
        /** * the Student * constructor@constructor* /
        function Student() {
           this.num = 'Tom';
        }
    
        // 1. Construct an instance of the parent class
        var p = new Person();
        // 2. And set it to the prototype object of the subclass
        Student.prototype = p;
        // 3. Fix the constructor pointer
        Student.prototype.constructor = Student;
    
        var stu = new Student();
  
        console.log(stu); // Student {num: "Tom"}

        console.log(stu.num); // Tom
        stu.run(); / / run
        console.log(stu.name); // Jack
        console.log(stu.lore); // ["html", "css"]

        console.log(stu.constructor.name); // Student
    
    </script>
Copy the code

The illustration

Problem: Inherited instance attributes, if of reference type, are shared by multiple instances of subclasses

Note: At this point, stereotype chain inheritance is over

Inheritance – Prototype chain inheritance -4

Thinking: As long as the prototype object is shared, it must be shared.

The solution

1. Add it to the object itself

(1) Add objects after they have been created (poor reusability, high redundancy, poor stability, not recommended).

(2) Add it inside the constructor

function Stu () {
   this.num = '20210819';

   // It must be written exactly like the parent class
   this.name = 'Rose';
   this.lore = ['js'.'jquery'];
}
Copy the code

Optimization: You can call the parent constructor directly, but you need to modify the this pointer

 function Stu() {
    this.num = '20210819';

    // It must be written exactly like the parent class
    // this.name = 'Rose';
    // this.lore = ['js', 'jquery'];

    Person.call(this);
}
Copy the code

Reoptimization: pay attention to the overwriting relationship, if the same name, should, subclass overwrite the parent class

 function Stu() {
    Person.call(this);
    this.num = '20210819';

    // It must be written exactly like the parent class
    // this.name = 'Rose';
    // this.lore = ['js', 'jquery'];

}
Copy the code

The illustration

The Student function already obtains the name and lore of the Person function.

Concept: “borrowed constructor inheritance”, inside the child constructor, calling the parent constructor

Note: Since this point, we have covered both stereotype chain inheritance and helper constructor inheritance, calling it “combinatorial inheritance” = stereotype chain + helper constructor

Problem: Arguments to the parent constructor cannot be modified

Inheritance – Prototype chain inheritance -5

The solution

  1. Parent class constructor that needs to be set to receive variable arguments
  2. When the subclass constructor calls the superclass constructor, it simply passes arguments
    <script>
        /** * the Person * constructor@constructor* /
        function Person(name, lore) {
            this.name = name;
            this.lore = lore;
        }

        Person.prototype.run = function () {
            console.log('run');
        };


        /** * the Student * constructor@constructor* /
        function Student(num, name, lore) {
            // Note: it must be placed first
            Person.call(this, name, lore);
            this.num = num;
        }

        // 1. Construct an instance of the parent class
        var p = new Person();
        // 2. And set it to the prototype object of the subclass
        Student.prototype = p;
        // 3. Fix the constructor pointer
        Student.prototype.constructor = Student;

        var stu = new Student('001'.'Joe'['html']);
        var stu2 = new Student('002'.'bill'['css']);
        console.log(stu);
        console.log(stu2);
    </script>
Copy the code

Problem: Duplicate superclass attributes, one on the instance, one on the prototype object. (As shown below)

5. Inheritance – Prototype chain inheritance -6

Train of thought

1. Understand why there are two copies?

Because the superclass constructor is called twice

  • 1, inside the subclass constructor
  • 2 times, when creating the subclass constructor prototype object

Analysis of the

What is the meaning of two calls?

  • 1, inside the subclass constructor
    • To get instance properties of the parent class
  • 2 times, when creating the subclass constructor prototype object
    • To get instance properties of the parent class
    • To get the stereotype object properties of the instance

Conclusion: When trying to set the stereotype object of the subclass constructor, only the stereotype object property of the superclass constructor is required

The solution

Plan 1:

Modify the prototype object pointer of the subclass constructor to the prototype object of the superclass constructor

Question:

  • Shared prototype objects
  • Prone to conflict
  • Unable to determine the type

Do not use!!!!!!

Scheme 2:

Ideas:

Can I change the prototype object pointer of the subclass constructor to an object

This object can only access the properties/methods of the superclass prototype object, right?

The solution

  1. copyThe prototype object of the parent constructor
    • Note: this refers to copying the contents of the prototype object, not the entire address
    • I’ll show you how to copy it, and then I’ll implement it myself, okay
  2. An empty object instance is created using the prototype object of the parent constructor

The illustration

concept

1. Original type inheritance

Use prototypes, and then create new objects based on existing objects; There is no need to create custom types

The core

function createObjWithObj(obj) {
    function Tmp() {}
    Tmp.prototype = obj;
    var o = new Tmp();
    return o;
}
Copy the code

The system implements Object.create

1. The role

  • Creates an object and sets the prototype object of that object as the parameter passed in
  • Compatible with ES5 but not IE8

2. Simple usage

var obj = {name:"sz"};
var obj2 = Object.create(obj);
        // Create an empty object obj2
        // use obj as the prototype object of obj2
Copy the code

3. Compatible processing

if(typeof Object.create == "function") {
    var o = Object.create(obj);
} else {
    Object.create = function(){
        function F(){};
        F.prototype = obj;
        var o = newF(); }}Copy the code

2. Parasitic inheritance

To enhance the object, by adding, you mean to add more properties or methods to the object

The core

function createNewObjWithObj(obj) {
    // 1. Create a new object from another object
    var o = createObjWithObj(obj);
    // 2. Add objects
    o.name = 'sz';
    o.age = 18;
    // 3. Return the object
    return o;
}
Copy the code

Inheritance – prototype chain inheritance – summary

1. Call the parent constructor from the child constructor using constructor inheritance for instance attributes of the parent constructor

  • Note that the this pointer is modified
  • Note the call order, first inside the subclass constructor

2. Stereotype object properties for the parent constructor

  1. Prototype chain inheritance
  2. Parasitic inheritance

3. The graphic

Seven, conclusion

Here we end the inherited knowledge, tomorrow we will do some exercises to consolidate ha, there is a copy of the property we talked about before, also give him full.

Feel free to head over to the column for other related articles: JavaScript knowledge

Code calligraphy and painting is not easy, if you feel helpful, feel good, welcome to like collection ~

Of course, as it is a personal arrangement, inevitably there will be mistakes, welcome to leave a comment feedback.