One, foreword

I plan to write an in-depth series of JavaScript, which is mainly used to sort out the knowledge points and difficulties related to JavaScript, as well as review the original knowledge. This article focuses on the definitions of constructors, stereotypes, and prototype chains, and the relationships between them. How to form a prototype chain through an internal pointer to a prototype object? How to detect prototype, prototype chain, etc.

Second, the prototype

constructor

Before we get into prototypes, we need to know what a constructor is. Let’s take a look at an example:

   function Person() {}

   const p = new Person();
Copy the code

The above example is a constructor. The JavaScript default function is capitalized as a constructor and must be called with the new keyword. The above code creates a constructor named Person and generates an instance object p from the new instance as follows:

      console.log(p.constructor === Person);   // true
Copy the code

The following diagram shows the relationship between instance P and the constructor Person:

Note: From the above print, instance P should have a constructor attribute pointing to the Person constructor, which it does not. P itself does not have a constructor attribute, although p.constructor points to Person. Principle is p.c onstructor is delegated to the Person. The prototype, and the Person. The prototype. The constructor when the default to the Person.

2, the prototype

JavaScript dictates that every function has a Prototype property, which is a pointer to a prototype object that can contain properties and methods shared by all instances of a particular type. As follows:

    function Person() {}
    Person.prototype.name = 'zhangSan';
    Person.prototype.age = 35;
    Person.prototype.showInfo = function () {
        console.log(this.name, this.age);
    }

    const p1 = new Person();
    const p2 = new Person();
    console.log(p1.name, p2.name);  // zhangSan zhangSan
    console.log(p1.showInfo === p2.showInfo); // true
    console.log(p1.prototype.constructor === Person); // true

Copy the code

As you can see from the above example, an empty constructor is createdPersonAdd attributes and methods to the Person prototype propertyName, age, showInfoAnd in the newly created instance object, these properties and methods are shared by the instance. So what does the Prototype attribute point to? As you can see from the example, the Prototype property points to an object calledPrototype object (Person.prototype)The constructor property of the prototype object points to the Person constructor.

3, _proto_

__proto__ is a special built-in attribute in JavaScript objects, that is, a reference to another object. Each time a new instance is created, it contains a pointer (__proto__) to the prototype object.

  function Person() {}
  const p = new Person();
  console.log(p.__proto__ === Person.prototype); // true
Copy the code

At this point, you can see the relationship between constructors, prototype objects, and instances as follows:

Summary: Each constructor has a prototype object, which contains a pointer to the constructor, and instances contain an internal pointer to the prototype object.

3. Prototype chain

To speak before the prototype chain, review the first began to speak of, Person. The prototype. The constructor default is to point to the Person, if create a new object instead of the Person. The prototype of the reference, then what will happen? Here’s an example:

    function Person() {}

    Person.prototype = {
        name: 'zhangSan',
    }
    const p = new Person();
    console.log(p.constructor === Person); // false
    console.log(p.constructor === Object); // true
Copy the code

Why the Person see results. The prototype. The constructor to Object? Person.prototype does not automatically get the. Constructor attribute because you changed the reference to Person.prototype. Person. Prototype the default constructor attribute has been changed, so there is no constructor attribute on this object. It continues to delegate, delegating to the topmost Object.prototype whose.constructor points to Object. So how do you get P.constructor to point to Person? Just create a constructor property in Person.prototype like this:

    function Person() {}

    Person.prototype = {
        constructor: Person,
        name: 'zhangSan',
    }
    const p = new Person();
    console.log(p.constructor === Person); // true
    console.log(p.constructor === Object); // false
    console.log(Object.prototype.__proto__); // null
Copy the code

So update the above picture as follows:

Summary: When looking for instance attributes, if none are found, it looks for attributes associated with the stereotype, all the way up to the top level. This forms a chain of instances and prototypes, called a prototype chain. May not understand what is a prototype chain, and then in the way of prototype chain inheritance, specific explanation of the composition of the prototype chain.

function Person() {} function Man() {} Man.prototype = new Person(); // Const m = new Man(); console.log(m.constructor); // Person console.log(Man.prototype.__proto__ === Person.prototype); // true console.log(Person.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__ === null); // trueCopy the code

The above code creates two constructors Person, the Man, the third line of code to change the Man. The prototype of the reference, is essentially rewrote the prototype object of Man, Man. The prototype. The constructor is not pointing to the default of Man, but to the Person instance, The constructor of an instance of Person delegates to Person.prototype, so m.Constructor points to Person, and such a process forms the prototype chain. As shown in figure:

In the figure above, the prototype chain is formed by a chain of associated __proto__ connections.

4, methods,

1) isPrototypeOf() method

Prototype is not accessible in real life, but you can use a method (isPrototypeOf()) to determine if the relationship exists between objects, returning true if it does, false otherwise. Take the above example as follows:

   console.log(Man.prototype.isPrototypeOf(m)); // true
   console.log(Person.prototype.isPrototypeOf(m)); // true
   console.log(Object.prototype.isPrototypeOf(m)); // true
Copy the code

Prototype = man.prototype; prototype = isPrototypeOf(); man.prototype = isPrototypeOf(); All returns true.

2) getPrototypeOf() method

ES5 added object.getProtoTypeof () to return the prototype of the Object, that is, return prototype.

   console.log(Object.getPrototypeOf(m) === Man.prototype); // true
Copy the code
3) hasOwnProperty() method

The hasOwnProperty method checks whether an attribute exists in an instance.

    function Person() {}
    Person.prototype.age = 35;

    const p = new Person();
    p.name = 'zhangSan';

    console.log(p.hasOwnProperty('name')); // true
    console.log(p.hasOwnProperty('age')); // false

Copy the code

HasOwnProperty () can only determine properties of the object in the constructor, but cannot determine properties of the prototype object.

4) The in operator

The IN operator returns true when accessing a given property, whether it is on the stereotype object or the constructor.

    function Person() {}
    Person.prototype.age = 35;

    const p = new Person();
    p.name = 'zhangSan';

    console.log('name' in p); // true
    console.log('age' in p); // true

Copy the code

From above, using both in and hasOwnProperty() to determine that a property is on the prototype object, as long as the property is false on hasOwnProperty and true on IN, encapsulating as follows:

function hasOwnProtorypeProperty(object, name) { return ! object.hasOwnProperty(name) && (name in object); }Copy the code

5, conclusion

Constructor, prototype, instance, and the relationship between them. At the same time, the instance points to the inner pointer of the prototype Object, all the way to the top layer object.prototype, forming the prototype chain. If there is something wrong in the article, please point it out.

reference

JavaScript deep prototyping and prototype chain