Thoroughly understand JavaScript prototype and prototype chain

Thoroughly understand JavaScript prototype and prototype chain

Preface

Knowledge of prototypes and prototype chains has always been the focus of interviews. It is not too difficult, but it still takes some effort to fully understand it. Let's take a look at an interview question to whet your appetite:

function User() {}
User.prototype.sayHello = function() {}
var u1 = new User();
var u2 = new User();
console.log(u1.sayHello === u2.sayHello); 
console.log(User.prototype.constructor); 
console.log(User.prototype === Function.prototype); 
console.log(User.__proto__ === Function.prototype); 
console.log(User.__proto__ === Function.__proto__); 
console.log(u1.__proto__ === u2.__proto__); 
console.log(u1.__proto__ === User.__proto__); 
console.log(Function.__proto__ === Object.__proto__); 
console.log(Function.prototype.__proto__ === Object.prototype.__proto__); 
console.log(Function.prototype.__proto__ === Object.prototype); 

Laying the foundation

All JavaScript objects are essentially created through the new function, including objects defined in the form of object literals (equivalent to the syntactic sugar of new Object()).

All functions are essentially created through new Function, including Object, Array, etc.

All functions are objects.

prototype

Each function has a property prototype, which is the prototype. By default, it is an ordinary Object object, which is the prototype of the instance created by calling the constructor.

Contructor Properties

JavaScript also has a property that points to the constructor from the prototype: constructor, that is, Func.prototype.constructor --> Func

__proto__

All objects in JavaScript (except null) have a __proto__ property that points to the prototype of the object.

function User() {}
var u1 = new User();
// u1.__proto__ -> User.prototype
console.log(u1.__proto__ === User.prototype) // true

Obviously, the __proto__ property of the instance points to the prototype of the constructor, so will the __proto__ of multiple instances point to the same prototype?

var u2 = new User();
console.log(u1.__proto__ === u2.__proto__) // true

If the __proto__ of multiple instances all point to the prototype of the constructor, then if the instances can access the methods, properties, etc. on the prototype in a certain way, they can program on the prototype and achieve the effect of inheritance.

Let's continue to update the relationship diagram between prototypes and prototype chains:

Prototype chain

When an instance object is looking for an attribute, if it cannot find it, it will follow __proto__ to search for the prototype associated with the object. If it still cannot find it, it will look for the prototype of the prototype until it finds the top level. This is the concept of the prototype chain.

Let's take a look at some examples of prototype chains using interview questions:

Example

  1. u1.sayHello():
    There is no sayHello method on u1, so access u1.__proto__(User.prototype) and successfully access the sayHello method
  2. u2.toString()
    u2, User.prototype does not have a toString method, and User.prototype is also a normal object, so we continue to look for User.prototype.__proto__(Object.prototype) and successfully call the toString method

improve

After learning the above, most interview questions can be answered, such as the following

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); //1
console.log(new B().a); //undefined
console.log(new C(2).a); //2

But there is still something missing from solving the original interview questions in the article, such as Function.__proto__ === Object.__proto__, Function.prototype.__proto__ === Object.prototype.__proto__, etc. Let's tackle them one by one.

Object.__proto__ , Object.prototype, Object.prototype.__proto__

  • Object is the constructor. In the second part, we said that all functions are created through new Function, so Object is equivalent to an instance of Function, that is, Object.__proto__ --> Function.prototype.
  • Object.prototype is the prototype of the Object constructor, which is at the top of the prototype chain. Object.prototype.__proto__ has no upper prototype to point to, so its value is null.
// Summarize:
Object.__proto__ --> Function.prototype
Object.prototype.__proto__ --> null

Function.__proto__, Function.prototype, Function.prototype.__proto__

  • Function.prototype is the prototype of Function, which is the prototype of all function instances, such as Object.__proto__ mentioned above.
  • Function.prototype is a normal object, so Function.prototype.__proto__ --> Object.prototype
  • Function.__proto__: __proto__ points to the prototype of the constructor that created it. So who created Function?
    • Hypothesis: Function objects are also objects, so will Function.__proto__ point to Object.prototype? As mentioned above, Object.__proto__ --> Function.prototype. If Function.__proto__ -> Object.prototype, it always feels weird, who created whom, so I did some testing:

Practice proves that there is only Object.__proto__ --> Function.prototype

I have been thinking hard but have come up with no result. Could it be that Function is a monkey, jumping out from between the rocks? So I did a bunch of random tests, and unexpectedly found a clue.

From the above we can conclude: Function.__proto__ --> Function.prototype

Function is not created by anything and is added to memory when the JS engine starts.

Summarize

Finally, the knowledge about prototypes and prototype chains is condensed into a picture:

  1. The __proto__ of all functions (including Function) points to Function.prototype
  2. The __proto__ of a custom object instance points to the prototype of the constructor
  3. The __proto__ of the function's prototype points to Object.prototype
  4. Object.prototype.__proto__ --> null

Afterword

The ocean of knowledge is often vaster than you imagine. I have studied prototypes and prototype chains many times, and I think I have learned them more comprehensively and completely. But after encountering this interview question, I realized that what I had learned was just a branch, and there are really many deep treasures in JS waiting to be excavated. There is no end to learning, let us encourage each other.

Finally, here is a simple interview question to boost your confidence:

var F = function () {}
Object.prototype.a = function () {}
Function.prototype.b = function () {}

var f = new F();

console.log(fa, fb, Fa, Fb);

// Prototype chain // f.__proto__ --> F.prototype --> Object.prototype
// F.__proto__ --> Function.prototype --> Object.prototype

This is the end of this article about JavaScript prototype and prototype chain. For more relevant JavaScript prototype and prototype chain content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of prototypes and prototype chains in JavaScript
  • Detailed explanation of JavaScript prototype chain
  • JavaScript prototype and prototype chain details
  • Comprehensive analysis of prototypes, prototype objects, and prototype chains in js
  • In-depth understanding of javascript prototype and prototype chain

<<:  CSS Standard: vertical-align property

>>:  Analysis of the Docker deployment Consul configuration process

Recommend

The latest MySQL 5.7.23 installation and configuration graphic tutorial

The detailed installation and configuration of th...

Vue implements image drag and drop function

This article example shares the specific code of ...

Delete the image operation of none in docker images

Since I usually use the docker build command to g...

A brief analysis of the usage of USING and HAVING in MySQL

This article uses examples to illustrate the usag...

Example of how to upload a Docker image to a private repository

The image can be easily pushed directly to the Do...

Vue implements dynamic routing details

Table of contents 1. Front-end control 1. In the ...

Introduction to Semantic XHTML Tags

The first point to make is that people can judge t...

Nginx Layer 4 Load Balancing Configuration Guide

1. Introduction to Layer 4 Load Balancing What is...

Vue/react single page application back without refresh solution

Table of contents introduction Why bother? Commun...

Detailed explanation of the Sidecar mode in Docker Compose

Table of contents What is Docker Compose Requirem...

How to use mysql index merge

Index merging is an intelligent algorithm provide...

CSS solves the misalignment problem of inline-block

No more nonsense, post code HTML part <div cla...