[js basic review] Prototype and prototype chain

catalogue

  • What is the object
  • Constructor
  • Prototype object
  • Implement inheritance and different inheritance methods

object

Why object-oriented programming

The code logic migration is more flexible, the code reusability is high, and the code is highly modular

Constructor

function Person(name) {
    this.name = name
    
    this.getName = function(name) {
        return name
    }
}
const person = new Person()
  • this inside the function body points to the generated instance object
  • The generated object is instantiated with the new keyword
  • It can be used for initialization and parameter transfer

Process of new instance

  1. Create an empty object as the returned object instance
  2. The prototype object that generates the empty object points to the prototype property of the constructor
  3. Assign the current instance object to the internal this
  4. Execute constructor initialization code
function myNew(Fn, params) {
    // Create an empty object as the returned object instance, and__ proto__ Property points to the prototype of the constructor (Fn.prototype)
    const obj = Object.create(Fn.prototype)
    // Assign the current instance object to the internal 'this' and execute the constructor initialization code
    const result = Fn.apply(obj, params)
    return (result && (typeof result === 'object' || typeof result === 'function')) ? result : obj
}

How to create a constructor without news instantiation (not externally perceived)

function Person() {
    // Judge whether it is a new instance object
    if(!this instanceof Person) {
         return new Person()  
    }
    this.name = "Tom";
    this.getName = function() {
        return this.name
    }
}

const person = Person();

Disadvantages of using constructors

  • The methods in the constructor will exist in each generated instance object. Repeated mounting will actually lead to a waste of resources.

Therefore, we should use prototype objects to solve the above problems.

Prototype object

Each function has an attribute - prototype. The attribute value of this prototype is an object (a collection of attributes). By default, there is only one attribute called constructor, which points to the function itself. As shown in the figure below:

In the figure above, SuperType is a function, and the box on the right is its prototype.

Since the prototype is an object (a collection of attributes), in addition to the constructor, you can also customize many attributes, such as the following:

function Person(name) {
    this.name = name;
}
// Assign the attribute of the prototype object as the inherited attribute on the instance object to avoid repeated mounting methods
Person.prototype.getName = function() {
    return this.name
}

"Implicit prototype" proto

Each object has one__ proto__ Property to the prototype of the constructor that created the object.

Note: object Prototype is indeed a special case - its__ proto__ Point to null, remember!!!

As can be seen from the above figure: user defined function foo__ proto__ Point to function prototype´╝îObject.__proto__ Point to function prototype.

But why function__ proto__ Point to function What about prototype?
In fact, the reason is very simple: Function is also a Function, Function is an object, and there are__ proto__ Properties. Since it is a Function, it must be created by Function. So Function is created by itself. So it's__ proto__ Points to its Prototype

Last question: function The object that prototype points to, and its__ proto__ Does it also point to object prototype´╝č
The answer is yes. Because function The Object pointed to by prototype is also an ordinary Object created by Object, so it also follows the basic rules.

inherit

  • Prototype chain inheritance
function Person() {
    
}
Person.prototype.getName = function() {
    return this.name
}

function Man() {
    
}
Man.prototype = new Person();
Man.prototype.constructor = Man

Essence: the way to re prototype an object, taking the attributes and methods of the parent object as the attributes and methods of the child object prototype object

Disadvantages:

  1. Once the parent class attribute is assigned to the prototype attribute of the child class, the attribute belongs to the shared attribute of the child class
  2. When instantiating a subclass, you cannot pass parameters to the parent class
  • Constructor inheritance
function Person() {
    
}
Person.prototype.getName = function() {
    return this.name
}

function Man(arg) {
    Person.call(this,arg)   
}
// Solved the problem of shared attributes + parameter transfer from child to parent
  • Combinatorial inheritance
function Person() {
    
}
Person.prototype.getName = function() {
    return this.name
}

function Man(arg) {
    Person.call(this,arg)   
}
Man.prototype = new Person();
Man.prototype.constructor = Man

Disadvantages: no matter what scenario, the parent constructor will be called twice

  1. Initialize subclass prototype
  2. When a subclass calls the internal call parent class of a function
  • Parasitic combinatorial inheritance
function Person() {
    
}
Person.prototype.getName = function() {
    return this.name
}

function Man(arg) {
    Person.call(this,arg)   
}
Man.prototype = Object.create(Person.prototype);
Man.prototype.constructor = Man

How to implement multiple inheritance

function Person(name) {
    this.name = name
}
Person.prototype.getName = function() {
    return this.name
}
function Worker(salary) {
    this.salary = salary
}
Worker.prototype.getSalary = function() {
    return this.salary
}

function Man(arg) {
    Person.call(this,arg) 
    Worker.call(this,arg)   
    
}
Man.prototype = Object.create(Person.prototype);
Object.assign(Man.prototype, Worker.prototype);
Man.prototype.constructor = Man

Reference articles

Keywords: Javascript inheritance

Added by 1veedo on Sat, 12 Feb 2022 11:03:21 +0200