preface

Hi, I’m Lin Sanxin. I’m sure you’ve all heard of the three mountains in the front end: closures, prototype chains and scopes. And I’ve always felt that foundations are the prerequisite for advancement, so we can’t ignore them just because they are foundations. Today I’m going to talk about the prototype chain in my way, and I hope you have a solid grasp of the prototype chain

Many articles throw this diagram at the beginning, but I don’t like it, I think it is not good for the students with poor foundation, I like to lead you to realize this diagram from zero, in the realization process, constantly master all the knowledge of the prototype chain!! Come on!! Follow me from zero!! Follow me to tame the prototype chain!!

The prototype and __proto__

What is

What are these two things?

  • Prototype: Explicit prototype
  • __ proto__: Implicit prototype

What does it matter?

So these are both archetypes, so what’s the relationship between them?

In general, the constructor’s prototype and __proto__ refer to the same place, which is called the prototype object

So what is a constructor? A function that can be used as a new function is called a constructor, and arrow functions cannot be used as constructors

function Person(name, age) { // This is the constructor
  this.name = name
  this.age = age
}

const person1 = new Person('Ming'.20) // This is an instance of the Person constructor
const person2 = new Person('little red'.30) // This is also an instance of the Person constructor
Copy the code

The prototype constructor points to the same place as the __proto__ constructor

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.sayName = function() {
  console.log(this.name)
}
console.log(Person.prototype) // { sayName: [Function] }

const person1 = new Person('Ming'.20)
console.log(person1.__proto__) // { sayName: [Function] }

const person2 = new Person('little red'.30)
console.log(person2.__proto__) // { sayName: [Function] }

console.log(Person.prototype === person1.__proto__) // true
console.log(Person.prototype === person2.__proto__) // true
Copy the code

function

We mentioned the constructor above, in fact, he is also a function, in fact, we usually define a function, there are no more than the following

function fn1(name, age) {
  console.log(I was `${name}This year, I${age}At the age of `)
}
fn1('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old

const fn2 = function(name, age){
  console.log(I was `${name}This year, I${age}At the age of `)
}
fn2('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old

const arrowFn = (name, age) = > {
  console.log(I was `${name}This year, I${age}At the age of `)
}
arrowFn('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old
Copy the code

Function is a constructor. Function is a constructor. Function is a constructor. So this is the same thing as this

const fn1 = new Function('name'.'age'.'console.log(' I am ${name}, I am ${age} years old ')')
fn1('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old

const fn2 = new Function('name'.'age'.'console.log(' I am ${name}, I am ${age} years old ')')
fn2('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old

const arrowFn = new Function('name'.'age'.'console.log(' I am ${name}, I am ${age} years old ')')
arrowFn('Lin Three Hearts'.10) // MY name is Lin Sanxin. I am 10 years old
Copy the code

The prototype constructor (fn1, fn2, arrowFn) is the same as the __proto__ constructor (fn1, fn2, arrowFn)

function fn1(name, age) {
  console.log(I was `${name}This year, I${age}At the age of `)}const fn2 = function(name, age){
  console.log(I was `${name}This year, I${age}At the age of `)}const arrowFn = (name, age) = > {
  console.log(I was `${name}This year, I${age}At the age of `)}console.log(Function.prototype === fn1.__proto__) // true
console.log(Function.prototype === fn2.__proto__) // true
console.log(Function.prototype === arrowFn.__proto__) // true
Copy the code

object

In our normal development, to create an object, we usually use the following methods.

  • The constructor creates the objectHe creates objects like thisFunction constructor, so we won’t discuss it here
  • Literals create objects
  • New Object Creates an Object
  • Object.create Creates an ObjectThe resulting object is an empty prototype, which is not discussed here
// The constructor creates an object
function Person(name, age) {
  this.name = name
  this.age = age
}
const person1 = new Person('Lin Three Hearts'.10)
console.log(person1) // Person {name: 'I ', age: 10}

// Create a literal object
const person2 = {name: 'Lin Three Hearts'.age: 10}
console.log(person2) // { name: '林三心', age: 10 }

// Create a new Object
const person3 = new Object()
person3.name = 'Lin Three Hearts'
person3.age = 10
console.log(person3) // { name: '林三心', age: 10 }

// Object.create Creates an Object
const person4 = Object.create({})
person4.name = 'Lin Three Hearts'
person4.age = 10
console.log(person4) // { name: '林三心', age: 10 }
Copy the code

Let’s look at the two ways to create a literal Object and a new Object. In fact, the essence of a literal Object is a new Object

// the literal creates the object
const person2 = {name: 'Lin Three Hearts'.age: 10}
console.log(person2) // { name: '林三心', age: 10 }Nature is// new Object creates an Object
const person2 = new Object()
person2.name = 'Lin Three Hearts'
person2.age = 10
console.log(person2) // { name: '林三心', age: 10 }
Copy the code

The prototype constructor and __proto__ refer to the same place. Person2 and person3 are both instances of the Object constructor

const person2 = {name: 'Lin Three Hearts'.age: 10}

const person3 = new Object()
person3.name = 'Lin Three Hearts'
person3.age = 10

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

The Function and the Object

That’s what we say

  • functionisFunction constructorAn instance of the
  • objectisObject constructorAn instance of the

And whose instances are the Function constructor and Object constructor?

  • function Object()It’s actually a function, so it’s a functionFunction constructorAn instance of the
  • function Function()It’s actually a function, so it’s also a functionFunction constructorAn instance of, yes, he is an instance of himself

We can test it out and find out

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

constructor

You point to me and I point to you. For example, if you are my wife, I must be your husband.

function fn() {}

console.log(fn.prototype) // {constructor: fn}
console.log(fn.prototype.constructor === fn) // true
Copy the code

Prototype chain

Person. The prototype and the Function. The prototype

Before we talk about prototype chains, let’s talk about these two things

  • Person. The prototype, it isConstructor PersonThe prototype object of
  • The Function prototype, he isConstructor FunctionThe prototype object of

I’ve talked about prototype objects, prototype objects, and you can see that both of these are essentially objects

New Object() is a new Object. Person.prototype and function.prototype are both instances of the constructor Object. Prototype and function. prototype both have __proto__ pointing to Object.prototype

We can verify that

function Person(){}

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

What is a prototype chain?

What is a prototype chain? In fact, the saying is: the __proto__ path is called the prototype chain

End of prototype chain

Object. Prototype is the end of the prototype chain. Object. Prototype has a __proto__ pointer to null, which is the end of the prototype chain

At this point, the whole prototype schematic drawing is finished!!

Prototype inheritance

Speaking of prototypes, I have to add that prototype inheritance means that instances can use methods in Prototype on the constructor

function Person(name) { // constructor
  this.name = name
}
Person.prototype.sayName = function() { // Add methods to the prototype object
  console.log(this.name)
}


const person = new Person('Lin Three Hearts') / / instance
// Use the constructor's prototype method
person.sayName() / / Lin three hearts
Copy the code

instanceof

Method of use

A instanceof B
Copy the code

Check whether B’s prototype is in A’s prototype chain

example

function Person(name) { // constructor
  this.name = name
}

const person = new Person('Lin Three Hearts') / / instance

console.log(Person instanceof Function) // true
console.log(Person instanceof Object) // true
console.log(person instanceof Person) // true
console.log(person instanceof Object) // true
Copy the code

exercises

The exercises are just for you to consolidate the knowledge of this article

The first question

var F = function() {};

Object.prototype.a = function() {
  console.log('a');
};

Function.prototype.b = function() {
  console.log('b');
}

var f = new F();

f.a();
f.b();

F.a();
F.b();
Copy the code

The answer

f.a(); // a
f.b(); // f.b is not a function

F.a(); // a
F.b(); // b
Copy the code

The second question

var A = function() {};
A.prototype.n = 1;
var b = new A();
A.prototype = {
  n: 2.m: 3
}
var c = new A();

console.log(b.n);
console.log(b.m);

console.log(c.n);
console.log(c.m);
Copy the code

The answer

console.log(b.n); / / 1
console.log(b.m); // undefined

console.log(c.n); / / 2
console.log(c.m); / / 3
Copy the code

The third question

var foo = {},
    F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';

console.log(foo.a);
console.log(foo.b);

console.log(F.a);
console.log(F.b);
Copy the code

The answer

console.log(foo.a); // value a
console.log(foo.b); // undefined

console.log(F.a); // value a
console.log(F.b); // value b
Copy the code

The fourth question

function A() {}
function B(a) {
    this.a = a;
}
function C(a) {
    if (a) {
        this.a = a;
    }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;

console.log(new A().a); 
console.log(new B().a);
console.log(new C(2).a);
Copy the code

The answer

console.log(new A().a); / / 1
console.log(new B().a); // undefined
console.log(new C(2).a); / / 2
Copy the code

The fifth problem

console.log(123['toString'].length + 123)
Copy the code

The answer: ToString = 1; toString = 1; toString = 1; toString = 1; toString = 1; 1 + 123 = 124. Why length is 1?

console.log(123['toString'].length + 123) / / 124
Copy the code

conclusion

If you think this article is a little bit helpful to you, click a like and encourage Lin Sanxin haha. Or you can join my shoal of fish. If you want to enter the learning group and shoal of fish, please click here to join shoal of fish. I will broadcast the mock interview at regular time and answer your questions