This is the first day of my participation in the August More text Challenge. For details, see: August More Text Challenge

In js, we use constructors to create new objects. Each constructor has a Prototype property value inside it. This property value is an object that contains properties and methods that can be shared by all instances of the constructor.

When we create an object using the constructor, the object will contain a pointer to the value of the constructor’s prototype property. In ES5, this pointer is called the object’s prototype. Normally we shouldn’t be able to get this value, but browsers now implement the proto property to allow us to access this property, but it’s best not to use this property because it’s not specified in the specification. ES5 has added an object.getPrototypeof () method that allows us to get the prototype of an Object.

What is a prototype chain?

When we access a property of an object, if the property doesn’t exist inside the object, then it will look for that property in its prototype object, and that prototype object will have its own prototype, and so on and so forth, the concept of a chain of prototypes. The end of the prototype chain is usually object.prototype, so that’s why new objects can use methods like toString().

Features:

JavaScript objects are passed by reference, and each new object entity we create does not have its own copy of the prototype. When we modify the prototype, the objects associated with it inherit the change.

How to get a prototype?

  1. p.__proto__

  2. p.constructor.prototype

  3. Object.getPrototypeOf(p)


var b = {a:1.b:2}

// The prototype of b points to Object
// a: 1
// b: 2
// [[Prototype]]: Object
/ / constructor: ƒ Object ()
/ / hasOwnProperty: ƒ hasOwnProperty ()
/ / isPrototypeOf: ƒ isPrototypeOf ()
/ / propertyIsEnumerable: ƒ propertyIsEnumerable ()
/ / toLocaleString: ƒ toLocaleString ()
/ / the toString: ƒ toString ()
/ / the valueOf: ƒ the valueOf ()
/ / __defineGetter__ : ƒ __defineGetter__ ()
/ / __defineSetter__ : ƒ __defineSetter__ ()
/ / __lookupGetter__ : ƒ __lookupGetter__ ()
/ / __lookupSetter__ : ƒ __lookupSetter__ ()
// get __proto__: ƒ __proto__()
// set __proto__: ƒ __proto__()

Copy the code

Prototype chain correlation method

  • IsPrototypeOf () This method returns true if the implicit prototype __proto__ refers to the object prototype on which the isPrototypeOf() method was called

  • Object.getprototypeof () gets the reference to the instance’s implicit prototype (proto)

  • HasOwnProperty () determines whether the property exists in its own instance

  • Object.keys() gets the name of an enumerable property on an Object instance

  • Object. GetOwnPropertyName () on the Object instance attribute name, whether it can be enumerated

  • For in gets an enumerable property on the instance & prototype

  • InstanceOf object instanceOf constructor, used to check whether the constructor’s prototype property is present in the prototype chain of an instance object.


function Person(){this.age = 100}
Person.prototype.name="zhan";
Person.prototype.sex='woman'
Person.prototype.sayName=function(){
    return this.name;
}

var person1 = new Person;
person1.name="wang";
person1.job='yanyuan'
Object.defineProperty(person1, "age", {value:"forever 18".enumerable:false});

Person.prototype.isPrototypeOf(person1); // true

Object.getPrototypeOf(person1) == Person.prototype // true

person1.hasOwnProperty("age");//true
person1.hasOwnProperty("sex"); // false because sex is a property of the stereotype, not of the instance itself

Object.keys(person1) // ["name", "job"]
Object.keys(Person.prototype) // ["name", "sex", "sayName"]

Object.getOwnPropertyNames(person1); // ["age", "name", "job"]
Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name", "sex", "sayName"]

for(var i in person1) console.log(i) // name job sex sayName
for(var i in Person.prototype) console.log(i) // name sex sayName

person1 instanceof Person //true
person1 instanceof Object // true
Copy the code

There are several ways to implement JavaScript inheritance

If you want to inherit, you must provide a parent class (who to inherit, provide inherited properties).

  1. Stereotype chain inheritance: make the stereotype of the new instance equal to the instance of the superclass.

    • The characteristics of
    1. The properties that an instance inherits are the properties of its constructor, the properties of its parent constructor, and the properties of its parent stereotype. (The new instance does not inherit the properties of the parent instance!)
    • disadvantages
    1. The new instance cannot pass arguments to the superclass constructor.
    2. Single inheritance.
    3. All new instances share the properties of the parent instance. (Properties on stereotypes are shared. If one instance modifies a stereotype property, the other instance’s stereotype property will also be modified!)
  2. Borrowing constructors (class-inherited) : Introducing the superclass constructor into the subclass function with.call() and.apply() (self-executing (copying) the superclass function in the subclass function)

    – features:

    1. Only the properties of the superclass constructor are inherited, not the properties of the superclass stereotype.
    2. Shortcomings 1, 2 and 3 of prototype chain inheritance are solved.
    3. You can inherit multiple constructor properties (call multiple).
    4. Arguments can be passed to a parent instance in a child instance.

    – faults:

    1. Only properties of the superclass constructor can be inherited.
    2. Constructor reuse is not possible. (Every time you use it, you have to call it again.)
    3. Each new instance has a copy of the superclass constructor, bloated.
  3. Combinatorial inheritance (combinatorial prototype chain inheritance and borrowed constructor inheritance) (commonly used) combines the best of both patterns, parameter passing and reuse

    • The characteristics of:
    1. Can inherit properties on the parent prototype, can pass parameters, reusable.
    2. The constructor properties introduced by each new instance are private.
    • disadvantagesThe superclass constructor is called twice (memory consuming). The subclass constructor replaces the prototype superclass constructor.
  4. Original type inheritance

    • Focus onWrap an object with a function and return the call to that function. The function becomes an instance or object that can add attributes at will. This is how object.create() works.
    • The characteristics of: Similar to copying an object and wrapping it in a function.
    • disadvantages:
    1. All instances inherit the properties on the stereotype.
    2. Reuse is not possible. (New instance properties are added later)
  5. Parasitic inheritance

    • Focus on: Is to put a shell around the original type inheritance.
    • advantages: There is no custom type created, because it is just a shell that returns the object (this), and this function becomes the new object created.
    • disadvantages: The prototype is not used and cannot be reused.
  6. Parasitic combinatorial inheritance (common)

    • parasitic: Returns an object within a function and then calls it
    • combinationThe prototype of the function is equal to another instance. 2, use apply or call to introduce another constructor in the function, which can pass arguments
    • Focus on: Fixed an issue with composite inheritance

/ / parent -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

function Person(name){ // Add parameters to the constructor
    this.name=name
    this.sayName =function(){
        alert(this.name)
    }
}
Person.prototype.age = 18; // Adds prototype properties to the constructor

// The prototype chain inherits ---------------------------
function Per(){
    this.name = 'panpan';
}
Per.prototype= new Person(); / / the key
var per1 = new Per();
console.log(per1.age); / / 18
// Instanceof determines whether an element is on another element's prototype chain
console.log(per1 instanceof Person); //true

// Inherit --------------------- from the constructor
function Con(){
    Person.call(this.'ava'); / / the key
    this.age = 21
}
var con1 = new Con()
console.log(con1.name) //ava
console.log(con1.age) / / 21
console.log(con1 instanceof Person) //false

// Combine prototype chain inheritance and borrow constructor inheritance
function SubType(name){
    Person.call(this,name); // Borrow the constructor pattern
}
SubType.prototype= new Person(); // Prototype chain inheritance
var sub = new SubType('lian')
console.log(sub.name) //lian inherits constructor attributes
console.log(sub.age) //18 Inherit the parent stereotype properties

// The original type inherits ---------------------------
// Encapsulate a function container that prints objects and hosts inherited prototypes
function content(obj){
    function F(){}
    F.prototype=obj; // Inherit the passed arguments
    return new F() // Return the function object
}
var sup = new Person(); // Get an instance of the parent class
var sup1 = content(sup)
console.log(sup1.age) //18 Inherit function attributes from the parent class

// Parasitic inheritance ----------------------
// Add a shell to the original type inheritance to pass parameters
function subObject(obj){
    var sub = content(obj)
    obj.name= 'pan';
    return sub
}
// After the declaration, it becomes an object that can add attributes
var sup2 = subObject(sup)
console.log(typeof subObject) //function
console.log(typeof sup2) //object
console.log(sup2.name) //pan

// Parasitic composite inheritance ---------------------
/ / the parasitic
function content(obj){
    function F(){}
    F.prototype=obj; // Inherit the passed arguments
    return new F() // Return the function object
}
// Content is another expression of an instance of F
var con = content(Person.prototype)
// The stereotype chain of the con instance (F instance) inherits the stereotype of the superclass function
// This is more like a stereotype chain inheritance, except that the attributes of the stereotype are inherited

/ /
function Sub(){
    Person.call(this) // Inherit the superclass constructor attributes
} // Solve the drawback of combining the constructor property to call twice

/ / the key
Sub.prototype = con; // Inherit the con instance
con.constructor = Sub; // Be sure to fix the instance
var sub1 = new Sub();
// The Sub instance inherits constructor attributes, superclass instances, and function attributes from con
console.log(sub1.age)
Copy the code