The prototype

concept

When a constructor is created, the default is to create and associate an object with the constructor and that object is the prototype

role

All properties and methods in the stereotype can be shared by all objects created with their associated constructor

Access to the prototype

Constructor name. Prototype Instantiated object.__proto __

Simple use of prototypes
  1. Use the dynamic nature of the object to add members to the prototype object
  2. Replace the prototype object directly (the core jQ approach is implemented using the idea of prototype replacement)
 function Person (name) {
      this.name = name
    }

    Person.prototype.fn = function () {
      console.log('hello world')
      console.log(this.name)
    }

    var p = new Person('little red')

    p.fn()
    p.name = 'XiaoLi'
    p.fn()
    console.log(Person.prototype)
    console.log(p)
Copy the code

1. prototype

The constructor call accesses the prototype object associated with the constructor

2. proto

Definition: an object has a built-in property, is the js internal use to find the prototype chain property, through this property can allow instance object directly access to the prototype

3. constructor

Meaning: The constructor of a prototype object points to its constructor. If the prototype object is replaced, this constructor property is inaccurate and needs to be manually supplemented

Prototype chain

Constructor and prototype relationships between JS native Objects

Considerations for prototyping

  • When objects access properties and methods, they look for them themselves, and if they don’t, they go back to the prototype. (Passing from level to level forms a prototype chain)
  • When we replace the prototype object, we replace the object A created by the constructor before and the object B created after the replacement. The prototypes of A and B are inconsistent.
  • The stereotype that the object can access is the one associated with the constructor at the moment the object is created

Extension and extension

The constructor

In many programming languages, such as Java, objectC,c++ and so on, there is the concept of class, class has private attributes, private methods and so on, through the class to achieve the inheritance of the object, but in ES5 and before, unlike the above languages, there is a strict concept of class. Js implements inheritance through constructors and prototype chains.

The characteristics of
  • The first letter must be uppercase to distinguish ordinary functions
  • Internally, this object is used to point to the instance object to be generated
  • Use the new keyword to generate instance objects (below is an implementation of the new keyword)
    var obj = new Date(a)// Can be decomposed into
    var obj = {};
    obj.__proto__ = Date.prototype;
    Base.call(obj)

Copy the code
disadvantages
  • All instance objects can inherit attributes and methods from constructor functions, but attributes cannot be shared between object instances.
  • If methods are inside constructors, these internal methods are created each time an instance object is new, and these methods cannot be shared between different instance objects, resulting in a waste of resources (hence the concept of prototypes).

Implementation methods (to list a few)

Constructor pattern (custom constructor)

The difference between a constructor and a normal function

// constructor
function Egperson (name,age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        alert(this.name); }}var person = new Egperson('mike'.'18'); //this-->person
person.sayName();  //'mike'


// A normal function
function egPerson (name,age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        alert(this.name);
     }
}
egPerson('alice'.'23'); //this-->window
window.sayName();  //'alice'

Copy the code

The factory pattern

function CreatePerson(name, age, gender){
    var obj = {};
    obj.name = name;
    obj.age = age;
    obj.gender = gender;
    // This prints as window due to function call mode
    console.log(this);
    return obj;
}
var p = CreatePerson("Xiao Ming".18."male");  // Call mode is how a function is called
Copy the code

The parasitic mode

functionCreatePerson(name, age, gender){ var obj = new Object(); obj.name = name; obj.age = age; obj.gender = gender; // This refers to the object created by new console.log(this);return obj;
}
var p = new CreatePerson("Xiao Ming", 18."male"); // Call mode is how a function is calledCopy the code

Dynamic prototype pattern

function Person(name, age, job) {
    / / property
    this.name = name;
    this.age = age;
    this.job = job;
    
    / / method
    if(typeof this.sayName ! ="function") {
        // All public methods are defined here
        Person.prototype.sayName = function() {
            alert(this.name);
        };

        Person.prototype.sayJob = function() {
            alert(this.job);
        };


        Person.prototype.sayAge = function() {
            alert(this.age); }; }}var person1 = new Person("Nicholas".29."Software Engineer");
var person2 = new Person("Greg".27."Doctor");

person1.sayName();        //Nicholas
person2.sayName();        //Greg


Copy the code

Js implementation of inheritance: hybrid inheritance, archetypal inheritance and classical inheritance, ES6 Class can also achieve inheritance

The Class,

Basically, ES6 classes can be seen as a syntactic candy that does most of what ES5 does. The new class writing method simply makes object prototype writing clearer and more like object-oriented programming syntax.

// ES5
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ') ';
};

var p = new Point(1.2);
// ES6

/ / define the class
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ') '; }}Copy the code

The characteristics of

  • The constructor function in class is the equivalent of the ES5 constructor (declare properties and static methods), which creates properties and methods based on the dynamic stereotype pattern constructor above. Personally, there are many similarities
  • When a method is defined in a class, it is not preceded by function or followed by a method that is defined in the prototype property of the class.
  • All methods defined internally by a class are not enumerable
  • Strict mode is default inside classes and modules
  • When a subclass inherits its parent class, it must call the super method from constructor otherwise it cannot create a new instance because the subclass does not have its own This object, but instead inherits its parent class’s This object to process it

A stereotype chain relationship in a class

Each object has a __proto__ attribute that points to the prototype attribute of the corresponding constructor. Class is the syntactic sugar of the constructor and has both the Prototype and __proto__ attributes, so there are two inheritance chains.

  1. The __proto__ attribute of a subclass, which indicates constructor inheritance, always points to the parent class.
  2. The __proto__ attribute of the prototype attribute, representing inheritance from instance methods, always points to the Prototype attribute of the parent class.
class A {}class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
Copy the code

An inherited internal implementation of a class

class A {}class B {}// Instance B inherits instance A
Object.setPrototypeOf(B.prototype, A.prototype);

// B inherits A's static attributes
Object.setPrototypeOf(B, A);

const b = new B();

Object.setPrototypeOf = function (obj, proto) {
  obj.__proto__ = proto;
  return obj;
}
Copy the code

As an object, the prototype (__proto__ attribute) of subclass (B) is the parent (A);

As a constructor, the prototype object (prototype property) of subclass (B) is an instance of the prototype object (Prototype property) of the parent class.

Object.create(A.prototype); // equivalent to b.prototype.__proto__ = a.prototype;Copy the code

The instanceprotoattribute

The __proto__ attribute of the __proto__ attribute of the subclass instance points to the __proto__ attribute of the parent class instance. That is, the prototype of a subclass is the prototype of its parent class.

var p1 = new Point(2, 3);
var p2 = new ColorPoint(2, 3, 'red');

p2.__proto__ === p1.__proto__ // false
p2.__proto__.__proto__ === p1.__proto__ // true

Copy the code

Class this refers to the problem

Class methods contain this inside, which by default points to instances of the class. But when the instance methods in the class are extracted and used, this points to the runtime environment.

(New react uses the same three methods to declare binding methods)

class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }

  // ...
}

class Logger {
  constructor() {
    this.printName = (name = 'there') = > {
      this.print(`Hello ${name}`);
    };
  }

  // ...
}

Copy the code

ES5 and ES6 implementation inheritance differences

  1. In ES5, inheritance essentially means that subclasses create their own this and then add the Parent class’s methods to this (using parent-apply (this)

  2. In ES6, you create an instance object of the parent class, this, and then modify this with the constructor of the subclass.