Home  >  Article  >  Web Front-end  >  Detailed explanation of prototype and parasitic inheritance in JS (code example)

Detailed explanation of prototype and parasitic inheritance in JS (code example)

不言
不言forward
2018-10-24 17:47:361951browse

This article brings you a detailed explanation (code example) of prototypal and parasitic inheritance in JS. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Foreword: I have recently been reading Javascript Advanced Programming. For me, the Chinese version of the book has a lot of unsatisfactory translations, so I try to interpret it using what I understand. If there are any mistakes or omissions, we will be very grateful for your pointing them out. Most of the content in this article is quoted from "JavaScript Advanced Programming, Third Edition".

Prototypal Inheritance

Douglas Crawford wrote an article in 2006 titled Prototypal Inhertitance in JavaScript (Prototypal Inheritance in JavaScript).

In this article, he introduces a method of implementing inheritance that does not use constructors in the strict sense.

The idea is to use prototypes to create new objects based on existing objects without having to create custom types.

In order to achieve this purpose, he gave the following function.

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

Inside the object() function, a temporary constructor is first created, then the passed in object is used as the prototype of this constructor, and finally a new instance object of this temporary type is returned.

Essentially, object() performs a shallow copy of the passed in object.

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

var person = {
    name: "Shaw",
    friends: ["Sharon", "Sandy", "Van"]
}

var person1 = object(person);

/*
person1 = function object(person){
    function F(){};
    F.prototype = person1;
    return new F();
}()

person1 = function object({
    name: "Shaw",
    friends: ["Sharon", "Sandy", "Van"]
}){
    function F(){};
    F.prototype = {
        name: "Shaw",
        friends: ["Sharon", "Sandy", "Van"]
    }
    return {
    }
}

person1 = {

};

{}.__proto__ = {
    name: "Shaw",
    friends: ["Sharon", "Sandy", "Van"]
}
*/

person1.name = "Roc";
person1.friends.push("Roster");

var person2 = object(person);

person2.name = "Linda";
person2.friends.push("Jobs");

console.log(person.friends); //["Sharon", "Sandy", "Van", "Roster", "Jobs"]
console.log(person1.friends); //["Sharon", "Sandy", "Van", "Roster", "Jobs"]
console.log(person2.friends); //["Sharon", "Sandy", "Van", "Roster", "Jobs"]

The prototypal inheritance advocated by Crockford requires that you must have an object that can serve as the basis for another object.

If there is such an object, you can pass it to the object() function, and then modify the obtained object according to specific needs.

ECMAscript5 standardizes prototypal inheritance through the new Object.create() method.
This method accepts two parameters: an object to be used as the prototype of the new object and (optionally) an object to define additional properties for the new object.

The Object.create() and object() methods behave the same when passing in a parameter.

var person = {
    name: "Shaw",
    friends: ["Sharon", "Sandy", "Van"]
}

var person1 = Object.create(person);
person1.name = "Roc";
person1.friends.push("Roster");

var person2 = Object.create(person);
person2.name = "Linda";
person2.friends.push("Messi");

console.log(person.friends); //["Sharon", "Sandy", "Van", "Roster", "Messi"]
console.log(person1.friends); //["Sharon", "Sandy", "Van", "Roster", "Messi"]
console.log(person2.friends); //["Sharon", "Sandy", "Van", "Roster", "Messi"]

The second parameter of the Object.create() method has the same format as the second parameter of the Object.defienProperties() method:

Each property is defined through its own descriptor of.

Any property specified in this way will override the property of the same name on the prototype object.

var person = {
    name: "Shaw",
    friends: ["Sharon", "Sandy", "Selina"]
}

var person1 = Object.create(person, {
    name: {
        value: "Roc"
    }
})

console.log(person1.name); //"Roc"

Browsers that support the Object.create() method include IE9, Firefox 4, Opera 12 and Chrome.

Applicable scenarios:

When there is no need to go to great lengths to create a constructor, but you just want to keep one object similar to another object, prototypal inheritance is fully capable.

It is important to remember that properties containing reference type values ​​will always share the corresponding value, just like using the prototype pattern.

Parasitic inheritance

Parasitic inheritance is an idea closely related to prototype inheritance, and it was also popularized by the great god Crockerford.

The idea of ​​parasitic inheritance is similar to the parasitic constructor and factory pattern.

Create a function that simply encapsulates the inheritance process, internally enhances the object in some way, and returns the object as if it really did all the work.

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

function createAnother(original) {
    var clone = object(original); //通过调用函数创建一个新对象
    clone.sayHi = function(){ //以某种方式来增强这个对象
        console.log("hi");
    }
    return clone; //返回这个对象
}

In this example, the createAnother() function receives a different parameter, which is the object that will be used as the basis for the new object.
Then, pass the object parameter (original) to the object() function, and assign the returned result to clone.

Add a new method sayHi() to the clone object, and finally return the clone object.

You can use the createAnother() function as follows:

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

function createAnother(original) {
    var clone = object(original); //通过调用函数创建一个新对象
    clone.sayHi = function(){ //以某种方式来增强这个对象
        console.log("hi");
    }
    return clone; //返回这个对象
}

var person = {
    name: "Shaw",
    friends: ["Sandy", "Sharon", "Van"]
}

var anotherPerson = createAnother(person);

anotherPerson.sayHi(); //"hi"

The code in this example returns a new object based on person - anotherPerson. The new object not only has all the properties and methods of person, but also has its own sayHi() method.

Parasitic inheritance is also a useful pattern when objects are the primary concern rather than custom types and constructors.

The object() function used in the previous demonstration of inheritance mode is not necessary. Any function that can return a new object is suitable for this mode.


The above is the detailed content of Detailed explanation of prototype and parasitic inheritance in JS (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete