17
头图

Preface

Hello, everyone, I’m Lin Sanxin. I believe everyone has heard of the three big mountains on the front end: closure, prototype chain, scope , these three are actually just basics. And I always think that the foundation is the prerequisite for advanced , so you can’t ignore them just because it is the foundation. Today I will talk about the prototype chain in my way. I hope everyone can firmly grasp the prototype chain knowledge

Many articles throw this picture as soon as they come up, but I don’t like this. I think it’s not good for students with a bad foundation. I like to lead everyone to implement this picture from scratch. In the process of implementation, keep mastering the prototype chain. All the knowledge! ! ! Come on! ! ! Follow me to achieve it from scratch! ! ! Follow me to tame the prototype chain! ! !

截屏2021-09-13 下午9.58.41.png

prototype and __proto__

What is it

What are these two things?

  • prototype: explicit prototype
  • __ proto__: implicit prototype

what is the relationship

So these two are called prototypes, so what is the relationship between them?

Generally, the prototype of the constructor instance point to the same place, which is called the prototype object

So what is a constructor? As the saying goes, new are called constructors, and arrow functions cannot be used as constructors.

function Person(name, age) { // 这个就是构造函数
  this.name = name
  this.age = age
}

const person1 = new Person('小明', 20) // 这个是Person构造函数的实例
const person2 = new Person('小红', 30) // 这个也是Person构造函数的实例

The prototype of the constructor instance point to the same place, we can verify it

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('小明', 20)
console.log(person1.__proto__) // { sayName: [Function] }

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

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

截屏2021-09-12 下午9.23.35.png

function

We mentioned the constructor above. In fact, it is also a function in the final analysis. In fact, we usually define functions. There are nothing more than the following

function fn1(name, age) {
  console.log(`我是${name}, 我今年${age}岁`)
}
fn1('林三心', 10) // 我是林三心, 我今年10岁

const fn2 = function(name, age){
  console.log(`我是${name}, 我今年${age}岁`)
}
fn2('林三心', 10) // 我是林三心, 我今年10岁

const arrowFn = (name, age) => {
  console.log(`我是${name}, 我今年${age}岁`)
}
arrowFn('林三心', 10) // 我是林三心, 我今年10岁

In fact, the essence of these types is the same (only consider the declaration of the function), and they can all be new Function . That's right, Function is also a constructor. The above wording is equivalent to the following wording

const fn1 = new Function('name', 'age', 'console.log(`我是${name}, 我今年${age}岁`)')
fn1('林三心', 10) // 我是林三心, 我今年10岁

const fn2 = new Function('name', 'age', 'console.log(`我是${name}, 我今年${age}岁`)')
fn2('林三心', 10) // 我是林三心, 我今年10岁

const arrowFn = new Function('name', 'age', 'console.log(`我是${name}, 我今年${age}岁`)')
arrowFn('林三心', 10) // 我是林三心, 我今年10岁

截屏2021-09-12 下午9.17.42.png

We have said before, constructor prototype and its instance __proto__ is pointing to the same place, where fn1,fn2,arrowFn fact are instance constructor Function, then we come to test it

function fn1(name, age) {
  console.log(`我是${name}, 我今年${age}岁`)
}

const fn2 = function(name, age){
  console.log(`我是${name}, 我今年${age}岁`)
}

const arrowFn = (name, age) => {
  console.log(`我是${name}, 我今年${age}岁`)
}

console.log(Function.prototype === fn1.__proto__) // true
console.log(Function.prototype === fn2.__proto__) // true
console.log(Function.prototype === arrowFn.__proto__) // true

截屏2021-09-12 下午9.29.00.png

Object

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

  • constructor creates objects. The objects he creates are all Function constructor, so I won’t discuss it here.
  • literal creation object
  • new Object to create an object
  • Object.create creates an object, and it creates an object with an empty prototype, which is not discussed here

    // 第一种:构造函数创建对象
    function Person(name, age) {
    this.name = name
    this.age = age
    }
    const person1 = new Person('林三心', 10)
    console.log(person1) // Person { name: '林三心', age: 10 }
    
    // 第二种:字面量创建对象
    const person2 = {name: '林三心', age: 10}
    console.log(person2) // { name: '林三心', age: 10 }
    
    // 第三种:new Object创建对象
    const person3 = new Object()
    person3.name = '林三心'
    person3.age = 10
    console.log(person3) // { name: '林三心', age: 10 }
    
    // 第四种:Object.create创建对象
    const person4 = Object.create({})
    person4.name = '林三心'
    person4.age = 10
    console.log(person4) // { name: '林三心', age: 10 }

    Let's take a look at the two ways to create an object with new Object to create an object. In fact, the essence of creating an object new Object to create an object.

    // 字面量创建对象
    const person2 = {name: '林三心', age: 10}
    console.log(person2) // { name: '林三心', age: 10 }
    
    本质是
    
    // new Object创建对象
    const person2 = new Object()
    person2.name = '林三心'
    person2.age = 10
    console.log(person2) // { name: '林三心', age: 10 }

截屏2021-09-12 下午9.52.47.png

We have said before, constructor prototype and its instance __proto__ is pointing to the same place, where person2,person3 fact are instance of Object constructor, that we have to verify it

const person2 = {name: '林三心', age: 10}

const person3 = new Object()
person3.name = '林三心'
person3.age = 10

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

截屏2021-09-12 下午9.58.31.png

Function and Object

We often say above

  • function is an instance of the Function constructor
  • object is an instance of the Object constructor

So who are the Function constructor and Object constructor?

  • function Object() is actually a function, so it is an instance of Function constructor
  • function Function() is actually a function, so he is also Function constructor, yes, he is an instance of himself

We can test it and we will know

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

截屏2021-09-12 下午10.12.40.png

constructor

The constructor and prototype are paired. You point to me and I point to you. For example, if you are my wife, then I must be your husband.

function fn() {}

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

截屏2021-09-12 下午10.35.40.png

Prototype chain

Person.prototype and Function.prototype

Before discussing the prototype chain, let’s talk about these two things first

  • Person.prototype, which is the prototype object constructor Person
  • Function.prototype, he is the prototype object constructor Function

All talked about prototype objects, prototype objects, you can know that these two are objects

Since it is a object, the essence must be created new Object() Since it was new Object() , it means that Person.prototype and Function.prototype are both instances of the constructor Object. It also shows that Person.prototype and Function.prototype __proto__ point to Object.prototype

We can verify

function Person(){}

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

截屏2021-09-12 下午10.46.41.png

What is a prototype chain?

What is a prototype chain? In fact, as the saying goes: The path of __proto__ is called the prototype chain

截屏2021-09-12 下午10.55.48.png

End of the prototype chain

As we saw above, all three prototype chains end in Object.prototype . Does that mean that Object.prototype is the end of the prototype chain? Actually not, Object.prototype actually also has __proto__, pointing to null, that is the end of the prototype chain

At this point, the entire prototype schematic diagram is finished! ! !

截屏2021-09-13 下午9.56.10.png

Prototype inheritance

Speaking of the prototype, I have to say add prototype inherited this knowledge point, prototypal inheritance is, instance can use method prototype on the constructor

function Person(name) { // 构造函数
  this.name = name
}
Person.prototype.sayName = function() { // 往原型对象添加方法
  console.log(this.name)
}


const person = new Person('林三心') // 实例
// 使用构造函数的prototype中的方法
person.sayName() // 林三心

截屏2021-09-12 下午11.10.41.png

instanceof

Instructions

A instanceof B

Function: judges whether the prototype of B is on the prototype chain of A

example

function Person(name) { // 构造函数
  this.name = name
}

const person = new Person('林三心') // 实例

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

Practice questions

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

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();

Answer

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

F.a(); // a
F.b(); // b

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);

Answer

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

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

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);

Answer

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

console.log(F.a); // value a
console.log(F.b); // value b

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);

Answer

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

Fifth question

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

Answer: 123 is a number, the nature of the number is new Number() , the number itself does not have the toString method, then follow __proto__ to function Number() prototype to find the toString method, the length of the toString method is 1, 1 + 123 = 124 , you can see 95% of people can't answer the question: What is the length of a function?

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

Concluding remarks

If you think this article is of little help to you, please give me a thumbs up and encourage Lin Sanxin haha. Or join my group haha, let's fish and learn together
image.png

Sunshine_Lin
2.1k 声望7.1k 粉丝