[Step-By-Step] Deep Analysis of High Frequency Interview Questions/Weekly 06

  Front end, html5, javascript, Programmer

This week’s interview questions list:

  • What is the basic idea of prototype chain inheritance? What are the advantages and disadvantages?
  • What is the basic idea of borrowing constructors and combinatorial inheritance? What are the advantages and disadvantages?
  • What is the basic idea of prototype inheritance? What are the advantages and disadvantages?
  • What is the basic idea of parasitic inheritance? What are the advantages and disadvantages?
  • What is the basic idea of parasitic combinatorial inheritance? What are the advantages and disadvantages?

This week is a succession project. Before you start, you need to know about constructors, prototypes and prototype chains.

More quality articles to stamp on: https://github.com/YvetteLau/ …

Constructor

Constructors differ from ordinary functions only in the way they are called. Any function can be called bynewOperator, it can be used as a constructor. Any function that does not passnewOperator, it is a normal function.

Instance ownershipConstructorProperty that returns the constructor that created the instance object.

function Person(name, age) {
    this.name = name;
    this.age = age;
}

var Yvette = new Person('刘小夕', 20);
console.log(Yvette.constructor === Person); //true

One thing to note is that in addition to the basic data typesconstructorOutside (nullAndundefinedNoconstructorAttributes),constructorProperty can be rewritten. Therefore, when detecting the object type,instanceofOperator ratiocontsrutorMore reliable.

function Person(name) {
    this.name = name;
}
function SuperType() { }
var Yvette = new Person('刘小夕');
console.log(Yvette.constructor); //[Function: Person]
Yvette.constructor = SuperType;
console.log(Yvette.constructor); //[Function: SuperType]

Prototype

Every function we create hasprototypeProperty that points to the prototype object of the function. Of prototype objectsuseAre properties and methods that can be shared by all instances of a particular type.

By default, all prototype objects automatically get oneconstructorProperty that contains a pointer to theprototypePointer to the function where the property is located.

When the constructor is called to create a new instance, the inside of the instance will contain a pointer to the constructor’s prototype object (which can be passed through the instance’s__proto__To access the prototype object of the constructor).

function Person(name) {
    this.name = name;
}
Person.prototype.sayName = function() {
    console.log(this.name);
}
var person1 = new Person('刘小夕');
var person2 = new Person('前端小姐姐');
//构造函数原型对象上的方法和属性被实例共享
person1.sayName();
person1.sayName(); 

Instance. __proto__ === constructor. prototype

Prototype chain

A brief review of the relationships among constructors, prototypes, and instances:

Each constructor has a prototype object, the prototype object contains a pointer to the constructor, and the instance contains an internal pointer that can execute the prototype object__protoVisit).

If we make the prototype object equal to an instance of another type, then the prototype object contains a pointer to another prototype, and accordingly, the other prototype also contains a pointer to another constructor. Adding another prototype is another type of instance, then the above relationship still holds, and thus the chain of instances and prototypes is formed step by step. This is the basic concept of prototype chain.

function SuperType() {
    this.type = 'animal';
}
SuperType.prototype.getType = function() {
    console.log(this.type);
}
function SubType() {

}
SubType.prototype = new SuperType();
SubType.prototype.sayHello = function() {
    console.log('hello');
}
function SimType(name) {
    this.name = name;
}
SimType.prototype = new SubType();
SimType.prototype.sayHi = function() {
    console.log('hi');
}
var instance = new SimType('刘小夕');
instance.getType();

A picture is worth a thousand words.

callinstance.getType()The following search steps are invoked:

  1. SearchinstanceExample
  2. SearchSimType.prototype
  3. SearchSubType.prototype
  4. SearchSuperType.prototype, foundgetTypeMethod

In case no attribute or method can be found, the search process always has to move forward one by one to the end of the prototype chain before stopping.

All reference types are inheritedObjectThis inheritance is also realized through the prototype chain. If inSuperType.prototypeNot yet foundgetType, will arriveObject.prototypeFind in (the figure drew a ring less).

25. Prototype chain inheritance

The basic idea of prototype chain inheritance is to use prototypes to let one reference type inherit the attributes and methods of another reference type.

Such asSubType.prototype = new SuperType();

function SuperType() {
    this.name = 'Yvette';
    this.colors = ['pink', 'blue', 'green'];
}
SuperType.prototype.getName = function () {
    return this.name;
}
function SubType() {
    this.age = 22;
}
SubType.prototype = new SuperType();
SubType.prototype.getAge = function() {
    return this.age;
}
SubType.prototype.constructor = SubType;
let instance1 = new SubType();
instance1.colors.push('yellow');
console.log(instance1.getName()); //'Yvette'
console.log(instance1.colors);//[ 'pink', 'blue', 'green', 'yellow' ]

let instance2 = new SubType();
console.log(instance2.colors);//[ 'pink', 'blue', 'green', 'yellow' ]

As can be seencolorsThe attribute is shared by all instances (instance1, instance2, …).

Disadvantages:

  1. When inheritance is realized through a prototype, the prototype becomes an instance of another type, the original instance attribute becomes the current prototype attribute, and the reference type attribute of the prototype is shared by all instances.
  2. When creating instances of subtypes, there is no way to pass parameters to supertype constructors without affecting all object instances.

26. Borrow constructors

Borrowing constructorTechnology, its basic idea is:

Call the supertype constructor in the subtype constructor.

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
function SubType(name) {
    SuperType.call(this, name);
}
let instance1 = new SubType('Yvette');
instance1.colors.push('yellow');
console.log(instance1.colors);//['pink', 'blue', 'green', yellow]

let instance2 = new SubType('Jack');
console.log(instance2.colors); //['pink', 'blue', 'green']

Advantages:

  1. You can pass parameters to superclasses
  2. The problem that the reference type value contained in the prototype is shared by all instances is solved

Disadvantages:

  1. Methods are defined in constructors, function reuse is impossible, and methods defined in supertype prototypes are invisible to subtypes.

27. Combination inheritance

Combination inheritance refers to an inheritance mode that combines prototype chain and borrowing constructor technology together to give full play to the advantages of both. Basic ideas:

The prototype chain is used to inherit the prototype attributes and methods, and the constructor is used to inherit the instance attributes. The method is defined on the prototype to realize function reuse, and each instance has its own attributes.

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
    console.log(this.name);
}
function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
SuberType.prototype = new SuperType();
SuberType.prototype.constructor = SuberType;
SuberType.prototype.sayAge = function () {
    console.log(this.age);
}
let instance1 = new SuberType('Yvette', 20);
instance1.colors.push('yellow');
console.log(instance1.colors); //[ 'pink', 'blue', 'green', 'yellow' ]
instance1.sayName(); //Yvette

let instance2 = new SuberType('Jack', 22);
console.log(instance2.colors); //[ 'pink', 'blue', 'green' ]
instance2.sayName();//Jack

Disadvantages:

  • In any case, the supertype constructor is called twice: once when the subtype prototype is created, and once inside the subtype constructor.

Advantages:

  • You can pass parameters to superclasses
  • Each instance has its own attributes
  • Function reuse is realized

28. Prototype inheritance

The Basic Idea of Prototype Inheritance;

Prototypes allow you to create new objects based on existing objects without creating custom types.

function object(o) {
    function F() { }
    F.prototype = o;
    return new F();
}

Inobject()Inside the function, a temporary constructor is first passed through, then the passed-in object is taken as the prototype of the constructor, and finally a new instance of the temporary type is returned. In essence,object()A shallow copy was performed on the incoming object.

ECMAScript5 by addingObject.create()The method standardizes prototype inheritance. This method receives two parameters: an object used as the prototype of the new object and (optionally) an object defining additional attributes for the new object (which can override the same name attribute on the prototype object). If a parameter is passed in,Object.create()Andobject()The method behaves the same.

var person = {
    name: 'Yvette',
    hobbies: ['reading', 'photography']
}
var person1 = Object.create(person);
person1.name = 'Jack';
person1.hobbies.push('coding');
var person2 = Object.create(person);
person2.name = 'Echo';
person2.hobbies.push('running');
console.log(person.hobbies);//[ 'reading', 'photography', 'coding', 'running' ]
console.log(person1.hobbies);//[ 'reading', 'photography', 'coding', 'running' ]

Prototype inheritance is competent when it is not necessary to create constructors and only to keep one object similar to another.

Disadvantages:

As with prototype chain implementation inheritance, attributes containing reference type values are shared by all instances.

29. Parasitic inheritance

Parasitic inheritance is closely related to prototype inheritance. The idea of parasitic inheritance is similar to that of parasitic constructors and factory patterns, that is, to create a function that is only used to encapsulate the inheritance process. The function has internally enhanced the object in some way, and finally returns the object as if it did all the work.

function createAnother(original) {
    var clone = object(original);//通过调用函数创建一个新对象
    clone.sayHi = function () {//以某种方式增强这个对象
        console.log('hi');
    };
    return clone;//返回这个对象
}
var person = {
    name: 'Yvette',
    hobbies: ['reading', 'photography']
};

var person2 = createAnother(person);
person2.sayHi(); //hi

Based onpersonA new object–person2, the new object not only haspersonAll properties and methods of, but also their ownsayHi()Methods. Parasitic inheritance is also a useful pattern when considering objects rather than custom types and constructors.

Disadvantages:

  • Using parasitic inheritance to add functions to objects is inefficient because it cannot reuse functions.
  • As with prototype chain implementation inheritance, attributes containing reference type values are shared by all instances.

30. Parasitic combinatorial inheritance

The so-called parasitic combinatorial inheritance is to inherit the attribute by borrowing the constructor and the method by blending the prototype chain. The basic idea is:

It is not necessary to call the super-type constructor in order to specify the prototype of the sub-type. What we need is only a copy of the super-type prototype. Essentially, we use parasitic inheritance to inherit the prototype of the super-type, and then assign the result to the prototype of the sub-type. The basic pattern of parasitic combinatorial inheritance is as follows:

function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType;//增强对象
    subType.prototype = prototype;//指定对象
}
  • Step 1: Create a copy of the supertype prototype
  • Step 2: AddconstructorAttribute
  • Step 3: Assign the newly created object to the prototype of the subtype

At this point, we can call theinheritPrototypeTo replace a statement that assigns a value to a subtype prototype:

function SuperType(name) {
    this.name = name;
    this.colors = ['pink', 'blue', 'green'];
}
//...code
function SuberType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
inheritPrototype(SuberType, SuperType);
//...code

Advantages:

The super class constructor is called only once, which is more efficient. AvoidSuberType.prototypeThe above create unnecessary and redundant attributes, while the prototype chain can remain unchanged.

Therefore, parasitic combination inheritance is the most rational inheritance paradigm for reference types.

ES6 inheritance

ClassInheritance can be achieved through the Extensions keyword, such as:

class SuperType {
    constructor(age) {
        this.age = age;
    }

    getAge() {
        console.log(this.age);
    }
}

class SubType extends SuperType {
    constructor(age, name) {
        super(age); // 调用父类的constructor(x, y)
        this.name = name;
    }

    getName() {
        console.log(this.name);
    }
}

let instance = new SubType(22, '刘小夕');
instance.getAge(); //22

For ES6classThe following explanations are required:

  1. The data type of a class is a function, and the class itself points to a constructor.
console.log(typeof SuperType);//function
console.log(SuperType === SuperType.prototype.constructor); //true
  1. All methods defined within the class are enumerable. (Methods on ES5 prototypes are enumerable by default)
Object.keys(SuperType.prototype);
  1. constructorThe method is the default method for the class, and is implemented bynewThis method is called automatically when the command generates an object instance. A class must haveconstructorMethod, if there is no explicit definition, an emptyconstructorThe method is added by default.
  2. ClassCan’t call directly like the constructor, will throw an error.

UseextendsKeyword to achieve inheritance, one thing needs special instructions:

  • Subclass must be inconstructorCall insuperMethod, otherwise an error will be reported when creating a new instance. If no subclasses are definedconstructorMethod, this method will be added by default. In the constructor of subclasses, only callssuperBefore usethisKeyword, otherwise report an error. This is because the subclass instance is built. Based on the parent class instance, only the super method can call the parent class instance.
class SubType extends SuperType {
    constructor(...args) {
        super(...args);
    }
}

Reference articles:

[1]CSS- clear float

[2]The detailed explanation JS function Corellization

[3]JavaScript array deduplication

Thank you for your friends’ willingness to spend precious time reading this article. If this article gives you some help or inspiration, please don’t be stingy with your praise and Star. Your affirmation is my greatest motivation to move forward.https://github.com/YvetteLau/ …

Recommend to pay attention to my public number:

clipboard.png