• 1. Constructor

1.1 What is a constructor

First, a constructor is a normal function, created just like a normal function, but constructors tend to start with a capital letter. Constructors differ from ordinary functions in the way they are called. Constructors need to be called with the new keyword.

1.2 Why constructors

The common attributes and methods of extracted objects are encapsulated into a class (that is, a template). By instantiating classes, these instantiated objects can have similar attributes and methods, thus reducing redundant codes and realizing code reuse.

function Star(name, skill) { this.name = name; this.skill = skill; } var star1 = new Star(' Andy lau ', 'sing ') var star2 = new Star(' Andy Lau ',' sing ') console.log(star1) // Star {name: "Andy Lau ", skill: } console.log(star2) //Star {name: "yizi ", skill:" yizi "}Copy the code

1.3 Execution process of constructor

The constructor is called with the new keyword, so the execution of the constructor, which is also the execution of the new, has the following four steps:

1. Create an empty object. 2. Set the prototype chain: set this object's __proto__ to the constructor's prototype; 3. Use the newly created object as the context for this; 4. If this function has a return value, it returns; Otherwise, a new object is returned by default.Copy the code
  • Prototype 2.

Whenever a function is created, a Prototype attribute is created for the function, pointing to the prototype object, according to specific rules. The prototype object also has a constructor property that refers back to the constructor associated with it. Each time the constructor is called to create an instance, the instance will have a __proto__ attribute pointing to the prototype object.

The relationship among the three is shown as follows:

  • judge
  1. instanceofOf the constructorprototypeProperty appears on the stereotype chain of an instance object, returning a Boolean value
function Star(name, skill) { this.name = name; this.skill = skill; } var star1 = new Star(' Andy Lau ', 'sing ') console.log(star1 instanceof Star) //trueCopy the code
  1. IsPrototypeOf () method that checks if an instance has __proto__ pointing to obj. Prototype
function Star(name, skill) { this.name = name; this.skill = skill; } var star1 = new Star (' Andy lau ', 'sing') console. The log (Star) prototype) isPrototypeOf (star1)) / / trueCopy the code
  • To obtain

Object.getprototypeof (Object) Gets the prototype of the specified Object

  • 3. The prototype chain

When accessing properties or methods through objects, the instance itself is searched first; If it does not, it looks for attributes or methods in the prototype Object to which __proto__ points. If it does not find one, it continues along __proto__ until it reaches the prototype Object. In this way, layer by layer searching up will form a chain structure called the prototype chain.

Prototype.prototype.__proto__ === null

Note: Adding a property of the same name to an instance of an object overshadows the property of the prototype object. It does not modify it, but blocks access to it

  • judge
  1. HasOwnPropertypeOf () determines whether a property is on an instance or a prototype object. Returns true if it exists on an instance of it
  2. In returns true on both instances and stereotypes
  • The enumeration
  1. The for… In returns all properties accessed through an object that can be enumerated, including instance and stereotype properties, in an indeterminate order
  2. Object.keys() returns a string of all enumerable attribute names on an Object instance, in an indeterminate order
  3. Object. GetOwnPropertyNames () lists all the instance attributes, whether or not can be enumerated (including the constructor), determine the enumeration order
  • 4. Inheritance

4.1 Inheritance of prototype chain

Prototype creates an instance of the parent and assigns that instance to the child

function Father(name) { this.name = name this.color = ['red','black','pink'] } Father.prototype.getName = () => { Console. log(' console.log ')} function Son(score) {this.score = score} Son. Prototype = new Father(' console.log ' new Son(34) son1.getName() console.log(son1.name, son1.color)Copy the code

Output result:

  • Disadvantages:

(1) Multiple instances’ operations on reference types will be tampered with

var son2 = new Son(99)
son1.color.push('gary')
console.log(son2.name)
console.log(son1.color)
console.log(son2.color)
Copy the code



(2) When creating a subclass instance, do not pass arguments to the parent class

4.2 Borrowing constructors

Use the parent class’s constructor to enhance an instance of a subclass, that is, copy an instance of the parent class to the subclass

function Father(name) { this.name = name this.color = ['red','black','pink'] this.getName = function () { Console. log(' I am the constructor method of the parent class ')}} function Son(name) {Father. } var stu2 = new Son(' Son ') var stu2 = new Son(' king ') console.log(stu1.name) console.log(stu1.color) console.log(stu2.name) console.log(stu2.color) stu1.getName()Copy the code

  • advantages

(1) Avoid the attribute of reference type being shared by all instances

Var stu1 = new Son(' gray') var stu2 = new Son(' gray') stu2.color.push('gray') console.log(stu1.name) console.log(stu1.color)  console.log(stu2.name) console.log(stu2.color)Copy the code



(2) Can pass a parameter to a parent class in a subclass

(3) Can implement multiple inheritance (call multiple parent object)

  • disadvantages

(1) Only the attributes and methods of the parent class instance can be inherited, but the prototype cannot be inherited. (2) Instances are not instances of the parent class, but instances of subclasses. (3) Functions cannot be reused

4.3 Combination Inheritance

The combination of the above two approaches realizes inheritance of stereotype properties or methods through the stereotype chain, and the constructor realizes inheritance of instance properties or methods

function Father(name) { this.name = name this.color = ['red','black','pink'] } Father.prototype.getName = () => { Console. log(' Father's method ')} function Son(name) {Father. Call (this, name); } son.prototype = new Father() // first call, Var stu1 = new Son(' yellow') var stu2 = new Son(' yellow') stu2.color.push('yellow') console.log(stu1.name) console.log(stu1.color) stu1.getName() console.log(stu2.name) console.log(stu2.color)Copy the code
  • advantages

(1) there is no problem with reference attribute sharing (2) parameters can be passed (3) functions can be reused

  • disadvantages

When an instance object is created using a subclass, the parent class is called twice, and two copies of the same properties and methods exist in the subclass prototype

4.4 Original type inheritance

Assign an object directly to the prototype of the empty object constructor using an empty object as a mediator

function Object(obj) { function F() {} F.prototype = obj return new F() } function Father(name) { this.name = name GetName = () => {console.log(' I am the Father of the method ')} var Father = new Var stu2 = Object(Father) var stu2 = Object(Father) stu2.color.push('yellow') console.log(stu1) console.log(stu1.name) console.log(stu1.color) console.log(stu2.color)Copy the code



Note: in ES5Object.create()Can replace the Object method above

var stu1 = Object.create(father)
Copy the code

  • disadvantages

Same as prototype chain inheritance

4.5 Parasitic inheritance

On the basis of the original type inheritance, enhance the object, return the constructor

function Object(obj) { function F() {} F.prototype = obj return new F() } function Father(name) { this.name = name This. Color = ['red','black','pink']} Father. Prototype = () => {console.log(' I am my Father's method ')} function creatAnother(original) { var clone = Object(original) clone.sayHi = function () { console.log('hi') } return clone } var Stu1 = creatAnother(new Father(' Father ')) var stu2 = creatAnother(new Father(' Father ')) stu2.color. console.log(stu1) console.log(stu1.name) console.log(stu1.color) stu1.sayHi() stu1.getName() console.log(stu2.name) console.log(stu2.color)Copy the code

  • disadvantages

(1) Function reuse cannot be realized. (2) parameter transfer cannot be achieved

4.6 Parasitic combination

Using a combination of borrowed constructors passing parameters and parasitic patterns, you get a copy of the parent’s prototype, inherit the parent’s prototype using the parasite, and then assign the returned new object to the child’s prototype

function Father(name) { this.name = name; This. Color = ['red','black','pink']} Father. Prototype = function () {console.log(' I am the parent method ')} Father Son(name, age) { Father.call(this, This.age = age} let prototype = object.create (Father. Prototype) // Get a prototype copy of the parent class Prototype. Constructor = constructor, Prototype sayHi = function () {console.log('hi')} let stu1 = Log (stu1.name, stu1.age) console.log(stu1.color) stu1.getName() stu1.sayhi () console.log(stu1.color) stu1.sayhi ()Copy the code

  • advantages

Is currently the most efficient inheritance method, which calls the parent constructor only once while keeping the stereotype chain unchanged

reference

  • There are eight inheritance schemes commonly used in JavaScript
  • 6 ways to inherit JS