js - A simple understanding of prototypes and prototype chains

foreword

There is a concept that needs to be clear, only the constructor has the .prototype object, the object does not have this attribute, __proto__ is just a non-standardized way of accessing the prototype object of the constructor of the object provided by the browser;

prototype (prototype object)

A function is an object. Each function has a prototype attribute, and this attribute is the prototype object of the function. The attributes or methods defined on the prototype object will be inherited by the instance object of the function, and the instance object can directly access the prototype. A property or method in an object.

The prototype object is equivalent to a template for creating an instance, which stores various properties and methods of the instance;

For example: Array.prototype stores all the methods about arrays;

console.log(Array.prototype);  //  filter,find,map,push,pop,some,sort...

The object has no prototype (I feel that this sentence is a bit problematic), as follows:

  console.log("123".prototype); 		// undefined
  console.log({
    
    name:'Eula'}.prototype); // undefined
  console.log((123).prototype);			// undefined
  console.log([123].prototype);			// undefined

_proto_ (connection of the prototype chain )

I don’t know if you have discovered the attribute __proto__ when debugging in the console. This attribute is actually an attribute automatically added to the instance by the JS engine when the instance is created. It is absolutely equal to the prototype attribute of its constructor
; That is to say, the __proto_ of the instance is the prototype object of this instance, but it is not recommended to directly access __proto__ in the code, __proto__ is also called the implicit prototype object.
as follows:

	console.log("123".__proto__); 			// String类型
    console.log({
    
     name: "Eula" }.__proto__);// Object类型
    console.log((123).__proto__);			// Number类型
    console.log([123].__proto__);			// Arrary类型

It prints as follows:

insert image description here
In fact, it is equivalent to the following code: the order is one-to-one correspondence:

	console.log(String.prototype);
    console.log(Object.prototype);
    console.log(Number.prototype);
    console.log(Array.prototype);

说明: Everything in js is an object, String, Object, Number, Array, etc. are built-in constructors of js. In js, because everything is an object, they can also be called built-in objects, and they have their own prototype objects. The topmost The prototype object of is Object;

The methods used by their instantiated objects will search the respective prototype objects layer by layer until they are found;

其实这就是原型链的概念

When an instance wants to access a certain attribute, it first searches in the instance itself. If it is not found, it continues to search along the __proto__ object. If it finds that the final __proto__ object is null and does not find it, it returns an error that the attribute is not found. , and returns the property value if found. And this search path concatenated by several __proto__ objects is called the prototype chain.

Actual combat:

	class Person {
    
    
        constructor(name) {
    
    
          this.name = name;
        }
        say() {
    
    
          console.log(this.name + ":这个仇,我记下了。");
        }
      }
      let Eula = new Person("优菈");
      console.log("__proto__:", Eula.__proto__);
      console.log("prototype:", Person.prototype);
      console.log(Eula.__proto__ === Person.prototype);// true

The print is as follows:
insert image description here
We can find Eula.__proto__ === Person.prototypethat the instantiated object can access the prototype object through __proto__; since it can be accessed, we can also add our own properties and methods on it, as follows:

  	 // 第一种添加方式
  	  注意此处添加函数不能使用箭头函数 否则this将指向window
  	 Eula.__proto__.fun = function() {
    
    
        console.log('this:',this);
        console.log("我的名字是:", this.name);
      };
      
      // 第二种添加方式
      Person.prototype.age = 18;
      Eula.fun();
      console.log(Eula);

It prints as follows:

insert image description here
Use these two methods to add attributes and methods respectively. It should be noted that the method is added in the first method 不能使用箭头函数, otherwise its pointing will point to window, so you will not be able to get the attributes under the Person class;


constructorAnd you can also access the constructor through the prototype object :

	console.log(Person);
    console.log(Eula.__proto__.constructor === Person); //true

It prints as follows:
insert image description here

In fact, the above case is classwritten by using, and functionthe effect achieved by replacing it with the form is actually the same, as follows:

因为: The essence of ES 6 classis function. It can be regarded as a syntactic sugar, which makes the writing of object prototypes clearer and more like the syntax of object-oriented programming.

	   function Person(name) {
    
    
        this.name = name;
        this.say = function() {
    
    
          console.log(this.name + ":这个仇,我记下了。");
        };
      }
      let Eula = new Person("优菈");
      Eula.__proto__.fun = function () {
    
    
        console.log("this:", this);
        console.log("我的名字是:", this.name);
      };
      Person.prototype.age = 18;;
      console.log("__proto__:", Eula.__proto__);
      console.log("prototype:", Person.prototype);
      console.log(Eula.__proto__ === Person.prototype);// true
      console.log(Eula.__proto__.constructor === Person); //true
      Eula.fun();//新增的方法

Here is a flowchart about prototypes, constructors, instances, and prototype chains: it is not difficult to understand

insert image description here

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/130578195