In-depth study of JS series is the witness of my phased growth. I hope to comb relevant JS knowledge more rigorously and objectively through the form of articles. I also hope to help more friends of front-end development to solve problems and look forward to our common progress.

If you think this series is good, welcome to like, comment, forward, your support is the biggest power OF my persistence.


Opening:

When Brendan Eich designed an object-oriented system for JavaScript, he borrowed from two prototype-based languages, Self and Smalltalk. The reason he chose a prototype-based object-oriented system was not because he was in a hurry. It was relatively simple to design. It’s because Brendan Eich never intended to add the concept of classes to Javascipt in the first place.

In class-centric object-oriented programming languages, the relationship between classes and objects can be thought of as the relationship between molds and castings. Objects are always created from classes, whereas in the idea of prototype programming, classes are not necessary and objects need not be created from a class.

JavaScript is a fully object-oriented language, and if you want to make better use of JavaScript object-oriented systems, prototypes and prototype chains are a difficult topic to get around,

Today we are going to learn about this knowledge.

Understand three important attributes:prototype,__proto__,constructor

See knowledge meaning, the so-called “chain” to describe is a kind of relationship, combined with the prototype two characters, can be understood as the relationship between the prototype, since is a kind of relationship, you need to maintain, just as we visit friends and relatives, the family is a kind of bond, the analogy in JavaScript – instance, object instance, function prototype Also has its own connection, And the bonds between them are these three important attributes:

Three important attributes:prototype,__proto__,constructor

prototype

Let’s take a look at the first property: Prototype

The so-called attribute refers to the characteristics of a thing. For example, one of the characteristics of a beautiful woman is “long legs”, which is the attribute of a beautiful woman. By analogy with JavaScript functions, each function has a prototype attribute, which is an innate trait. Function objects do not have this property. In JavaScript, everything is an object, so ordinary objects do not include function objects.

Let’s look at an example:

function Person() {}// It is written in the comments, but it needs to be noted that
// prototype is a function property.
Person.prototype.name = "Kevin";
var person1 = new Person();
var person2 = new Person();

console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
Copy the code

In the above code we create a constructor called Person and add a name attribute to the instance prototype with a value of “Kevin”;

Then two instance objects are created :person1 and person2.

When we print the name property on both instance objects, we print Kevin(try it for yourself).

We can’t help but wonder what the Person. Prototype is, and why the constructor’s instantiation object is accessible by adding attributes to it.

The prototype property of the Person function refers to an object. Prototype is also an object. (That’s a lot of objects.) This object is the prototype of the instance created by calling the constructor. This is the prototype for person1 and Person2 in this example.

For the sake of understanding, let’s break down the above paragraph:

  • 1. Call the constructor: Person
  • 2. What call is used: the new keyword
  • 3. What do I get: two instantiated objects person1 and person2
  • 4. What is the relationship between the instantiated object and the prototype: the prototype for person1 and Person2 is Person.prototype

So what is a prototype? To put it this way, every JavaScript object (except null) is associated with another object when it is created, which is called a prototype, and every object “inherits” properties from the prototype.

In the above code we did not add the name attribute directly to person1 and person2, but both objects have access to the name attribute.

We use a diagram to show the relationship between the constructor and the instance stereotype:

Now that we’ve sorted out the relationship between the constructor and the instance prototype, how do we represent the relationship between the instance and the instance prototype, i.e. person1 or person2 and Person.prototype? This is where __proto__, the second important attribute in our understanding of prototype chains, comes in

__proto__

What are the characteristics of this property?

This is actually a property that every JavaScript object (except null) has, called __proto__. This property points to the prototype of that object as a bridge between the instance object and the prototype of that instance. Again, functions have this property because they are objects.

Let’s look at a code example:

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

With the help of the second property, we can understand the diagram more fully:

The Person constructor and the instance object Person are associated by prototype and __proto__ with the instance prototype person. prototype. Does the instance stereotype have attributes pointing to the constructor or to the instance?

This is where we bring up our third attribute: constructor

constructor

There is no instance prototype-to-instance attribute, since a constructor may generate many instances, but there is a prototype-to-constructor attribute, which is our constructor — each stereotype has a constructor attribute that points to the associated constructor.

Let’s look at another example:

function Person() {}console.log(Person === Person.prototype.constructor); // true
Copy the code

Ok, here we will improve the relationship diagram:

Through the introduction of the three attributes, we can summarize:

function Person() {}var person = new Person();

console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
// Learn an ES5 method to get a prototype of an object
console.log(Object.getPrototypeOf(person) === Person.prototype) // true
Copy the code

In the above code we did the following:

  • 1. Declare the constructor Person;
  • 2. Calling Person with the new operator instantiates a Person object;
  • 3. Determine whether the instantiated object points to the instance prototype via __proto__;
  • 4. Check whether the corresponding constructor can be found by using constructor;
  • 5. Pass in an Object using object.getPrototypeof to find the corresponding prototype Object;

You learned about constructors. The relationship between instance prototypes, and instance objects. Next, let’s talk about the relationship between instance and prototype:

Examples and prototypes

When an instance property is read, if it cannot be found, it looks for the property in the stereotype associated with the object. If not, it looks for the stereotype until it reaches the topmost level.

Here’s another example:

  function Person() {

  }

  Person.prototype.name = 'Kevin';

  var person = new Person();

  person.name = 'Daisy';
  console.log(person.name) // Daisy

  delete person.name;
  console.log(person.name) // Kevin
Copy the code

In the example above, we add the name attribute to the instance person. When we print Person. name, the result will be Daisy

But when we delete the name attribute under person and read Person. name, we can still print Kevin. In fact, if we can’t find the name attribute in the Person object, we will get the name attribute from the person’s prototype, which is person.__proto__. In Person. Prototype, luckily we found the name property, which is Kevin.

But we can’t help but wonder, what if we don’t?

Let’s look at the next level of relationship archetypes archetypes

Prototype of prototype

As we mentioned earlier, a prototype is also an Object, so since it is an Object, there must be a constructor that creates it. This constructor is Object();

  var obj = new Object(a); obj.name ='Kevin';
  console.log(obj.name); // Kevin;
Copy the code

The prototype Object is generated by the Object constructor. The __proto__ instance points to the prototype constructor, so let’s enrich our diagram.

Here we have a further understanding of the relationship between constructors, instance objects, and instance stereotypes. With that said, it’s time to introduce the prototype chain.

Prototype chain

How about the Object. Prototype? Object is the Object of the root node.

  console.log(Object.prototype.__proto__ === null) // true
Copy the code

But what exactly does NULL mean?

To quote teacher Ruan Yifeng’s the Difference between undefined and Null:

Null means “no object”, meaning there should be no value.

Object. Prototype. proto = null; Object. Prototype has no prototype.

Object. Prototype = Object. Prototype = Object.

We can add NULL to the final diagram to complete it.

The chain of connected archetypes in the image above is the archetype chain, the red line

supplement

Finally, three things that you might not have noticed:

constructor

First, constructor, let’s look at an example:

function Person() {}var person = new Person();
console.log(person.constructor === Person); // true
Copy the code

When access to the person. The constructor when, in fact, the person is not in the constructor property, when cannot be read to the constructor property, can from the prototype of the person also is a person. Read in the prototype, just the prototype with this property, So:

person.constructor === Person.prototype.constructor
Copy the code

__proto__

The second is proto, which is a nonstandard method to access a prototype that most browsers support, but it doesn’t exist in Person.prototype. In fact, it comes from Object.prototype and is more of a getter/setter than an attribute. When obj.proto is used, it is understood that object.getProtoTypeof (obj) is returned.

Is it really inheritance?

Finally, inheritance. Earlier we said that “every object ‘inherits’ properties from its prototype.” In fact, inheritance is a very confusing term, to quote from JavaScript you Don’t Know:

Inheritance means copying operations, but JavaScript by default does not copy the properties of an object. Instead, JavaScript simply creates an association between two objects so that one object can access the properties and functions of the other through delegation, so it is more accurate to call it delegation than inheritance.

Reference:

  • 1. Javascript Design Patterns and Development Practices
  • JavaScript goes from prototype to prototype chain

Learn more about the JavaScript catalog

  • #1 [In-depth study of JS — Prototype and Prototype Chain]
  • #2: Lexical scope and dynamic scope
  • #3 [In-depth study of JS — implement Yamashita Text stack]
  • #4 【 In-depth study of JS – variable objects 】
  • #5 [In-depth study of JS — scope chain]
  • #6 [In-depth study of JS — This point in real Development Scenarios]
  • #7: The execution context of JS
  • #8: Js closures
  • #9 — Parameter passing by value
  • #10: Call and Apply
  • Class array objects and arguments
  • Learn more about the various ways to create objects in JS

Welcome to pay attention to my personal wechat public number – the universe of fingertips, more quality thinking dry goods