preface

In the world of Javascript, there is a saying that everything is an object.

OMG, are they really objects? Which value types (primitive data types) are also objects?

Answer: Of course not.

Specifically, for reference types, Javascript divides data types into primitive data types and reference data types.

The prototype object and prototype chain mentioned in this paper are only for the object, JS in the form of prototype chain, to ensure that methods and attributes in the object can be passed down, according to the object-oriented view, this is inheritance. And JS through the prototype chain to achieve object inheritance. (ES6 has since introduced the extends keyword to implement inheritance)

Before we get to the next section, let’s take a look at these four concepts:

  • JS has some built-in constructors, such as Object, Function, Array, Boolean, Number, String, Date, and so on.
  • JS divides objects (except null) into ordinary objects and function objects__proto__Property, the function object will have one moreprototypeProperty, that is, function objects have by default__proto__Properties andprototypeProperties.
  • __proto__A property is an object that has two properties,constructorand__proto__.
  • constructorProperty to record which constructor the instance was created by.

A prototype object

See my title, prototype object, so the prototype actually refers to an object, let’s think of it as a normal JS object.

Let’s look at a simple piece of code and get a sense of what a prototype is.

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

Dizzy? Don’t panic, based on the above code we can roughly draw the following image:

As you can see intuitively from the red arrows above, instance objects (person) can point to prototype objects via the __proto__ attribute, and constructors can point to prototype objects via the Prototype attribute.

__proto__ is not a standard attribute. Only some browsers implement __proto__. It is available in Google and Firefox. The Prototype property is a function-only property.

So where does a prototype object come from? You can think of it this way: every Javascript object (except null) is associated with another object when it is created. This object is called a prototype, and every object inherits properties from the prototype object.

Prototype chain

We’re done with the prototype, so you can understand it, right? How easy… What about the prototype chain?

If an object has a prototype, then the prototype of an object is also an object. When the prototype object is created, there must be another object associated with it. Does the prototype object also have a prototype? (You taste, you taste)

Bingo, as long as there is an Object, there is a prototype (except Object. Prototype Object), so the prototype Object also has its own prototype. The chain structure associated with the prototype is called prototype chain.

We compare the prototype on the prototype Object with the prototype on the Object constructor:

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

Therefore, our general transformation plan is as follows:

Since the prototype of a prototype Object is also an Object, we can also create it with new Object(), so the end of the prototype chain refers to Object.prototype, and the end points to null. The prototype has no Object. The prototype has no Object. The prototype has no Object.

So are we done with the prototype chain? Of course not.

Prototype: Function(); Function(); Object(); Function(); Function(); (Don’t ask me how I guessed…)

Let’s rework the diagram:Do you understand after looking at the picture? Are you a smart kid?

So let’s ignore the green arrow and verify it with the codeFunction.prototypeObject:

console.log(Function.prototype.__proto__ ===  Object.prototype); // true
console.log(Function.prototype.constructor === Function); // true
Copy the code

The three green arrows are all constructors that point to the function. prototype object via the __proto__ attribute. Functions are also objects, so functions have __proto__. The end of the Function’s prototype chain goes to function.prototype.

Let’s take a look at code verification:

console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype); // true
console.log(Person.__proto__ === Function.prototype); // true
Copy the code

role

So what’s the use of a prototype, a prototype chain? I think that’s what people care about, right? In fact, as I mentioned earlier, there are only two words “inheritance”.

Let’s go straight to the following code:

function Person(name) { this.name = name; } Person. Prototype = {age: '18 ', say() {console.log(this.age +' age '+ this.name +' eat three bowls of food '); }} var p1 = new Person(' Person '); Var p2 = new Person(' yellow '); p1.say(); // Eighteen-year-old Xiao Ming ate three bowls of rice. Eighteen-year-old Xiao Huang ate three bowls of riceCopy the code

We can see that p1 and P2 inherit the age property and say() method directly. We don’t have to add the age property to p1 and P2 separately, which is the benefit of inheritance.

Using prototypes to store attributes and methods that are common to instances can also greatly reduce memory consumption.