The past and present of JavaScript’s prototype and prototype chain (1)

The past and present of JavaScript

Don’t be frightened by the name of this feeling. I’m not going to tell the history of the prototype . This article just wants to help you understand why the prototype and the prototype chain is a unique language, and other languages (or the programming languages I’ve learned) have not seen this one. This is also the most puzzling puzzle for me to learn JavaScript from the C language.

prototype

1. First from JavaScript to create objects

As we all know, JavaScript is an object oriented language, but there is no concept of class (except the current ES6 standard). Personally feel that ES6 is a new standard encapsulated on ES5, and its essence is ES5. Therefore, mastering ES5 is the essence. There is no concept of class, but there must be the concept of object, and the object of JS is different from other object oriented languages (such as C++). Each object is based on a reference type, (such as Array/Date/Function, etc. that belongs to the reference type, with a specific reference to the fifth chapter of “JavaScript advanced programming (Third Edition)”) or a custom type.

reference type

The most common way to create objects before was (by creating a Object instance):

Var animal = new Object ();

After that, a method of creating an object literal is presented.

Var Animal= {

First of all, it is clear that an object must contain attributes and methods: name and type are definitely attributes, and say is definitely a method. Second, attributes have corresponding properties inside the browser, which are used by the internal JS engine.

1.1, talk about attributes in JS objects (Property).

Property

According to ES5 standard, attribute in addition to what we know in the impression of a name, a value, similar to the form of key value pairs, in fact, there is a large article inside the browser inside.

ES5

Attributes are divided into data attributes (‘Data Property’) and accessor properties (Accessor Property). The name and type that have just been defined are data attributes, and the basis for distinguishing data attributes and accessor data is that the accessor property has a [[Get]] and [[Set]] method and it does not contain a [[value]] feature (Attribute).

Accessor Property

[[Get]]

[[Set]]

[[value]]

Attribute

The data attribute contains 4 features: [[configurable]], [[Enumerable]], [[Writable]], and [[Value]].

[[configurable]]

[[Enumerable]]

[[Writable]]

[[Value]]

The accessor property contains 4 properties: [[Configurable]], [[Enumerable]], [[Get]], [[Set]].

[[Configurable]]

[[Enumerable]]

[[Get]]

[[Set]]

Although these features are internal use of browsers, ES5 still provides the interface for us to call:

Object.defineProperty (obj, prop, descriptor);

Take an example (in the Chrome console):

> Object.getOwnPropertyDescriptor (Person, “name”)

These 4 API details (such as compatibility) can be referred to: MDN

MDN

2. Create the advance of the JS object

Although both the Object constructor or the object literal can be used to create a single object, it is obvious that there is a clear flaw: this method of mixing object creation and object instantiation directly leads to code cannot be reused and a heap of repeated code will be generated, so to solve this problem This problem has created a new way to create objects — factory mode . This form begins to approach the instantiation of classes and objects in the C++ language, and is closer to the actual code development.

Constructor

Factory model

2.1. Factory model

A very image of the name, as soon as we hear the name, we know that there is a factory at that time. As long as we provide the raw materials, we can use the mold of the factory to help us create the objects we want (that is, the instantiation process).

Because ES5 is unable to create classes, you can only use functions to encapsulate the details of creating objects with specific interfaces. For example:

Function createAnimal (name, type) {

Although this approach solves the problem of object instantiation code repetition, it does not solve the problem of object recognition (that is, the object created in this way can’t know its type, for example, the object created by the second previous methods can know that the type of its object is Person). So there is another way to create objects.

2.2, constructor pattern

Constructors are a basic concept in the C++ language, whose function is to initialize calls after instantiating an object, and to perform some replication operations, which can be considered as an initialization function. Similarly, the constructor used by JS is different from C++ in nature, but its essence is the same. JS provides some native constructors such as Object/Array/String, etc., and can also create custom ones. For example:

Object/Array/String

Function Animal (name, type) {

This constructor has the following three features:

  • does not explicitly create object
  • There is no explicit creation of objects

    Assign attributes and methods directly to the this object

    No return statement

    In performing new operations, you will experience the following 4 steps:

  • creates an object
  • Create an object

    Assign the scope of the constructor to the new object (so the this pointer points to the new object).

    Execute the code in the constructor

    Return a new object

    At this time dog is an instance of Animal. According to the tradition of the C++ language, each instance must have an attribute called constructor, and JS is the same, and the constructor attribute of the instance in JS points to the Animal constructor.

    The first three methods create the same object, so take one and compare it with factory mode.

     

    It can be seen that the constructor method is indeed more than one attribute, and as to why these attributes are concentrated under __proto__, it is what we have to mention later.

    __proto__

    So we can identify the type of the object (such as the Animal type in this example) by the constructor attribute, which is verified by using instanceof.

    Instanceof

    Of course, using the constructor is not perfect, the main problem with using the constructor is that each method is created in each instance, that is, when we create the Animal object, the method inside is actually an instance of the Function object, that is, the same as:

    This.say = new Function (console.log (‘I am a ‘+ this.type);

    This leads to the creation of multiple instances of multiple function objects, which obviously increases memory consumption, and in order to solve this problem, we introduce the prototype mode.

    3, prototype model

    In Figure 1, we have found that each object, whatever the method is created, has a __proto__ attribute, which is the key to the connection of the prototype chain. In the last section, we have 4 steps to perform the operation of the new, of which second steps are such as According to the code, it is an assignment operation, that is, dog.__proto__ = Animal.prototype, which can be seen through console printing:

    __proto__

    __proto__

    Dog.__proto__ = Animal.prototype

    The past and present of JavaScript

     

    The way to create prototype patterns is to adopt such a form:

    Function Animal () {}

    The difference between prototype mode and constructor mode can be seen in the following diagram:

    Constructor pattern:

    The past and present of JavaScript

     

    Prototype mode:

    The past and present of JavaScript

     

    From the above two pictures, we can see the advantages and disadvantages of the prototype, and how to improve it. Can the integration of the two make full use of the advantages of the two? If you think so, that means you are right. This is the 3.2 subsection.

    In addition to the prototype assignment operation, we prefer to use object literal or new keyword to manipulate the prototype. But the use of object literals or new keywords has a very important knowledge point: , whether using object literal or new keywords, is to create a new object to replace the original prototype object .

    Whether using object literal or new keyword, it is to create a new object to replace the original prototype object.

    Is it abstract? A picture to tell you the truth:

    Code:

    Function Animal () {}

    Or:

    Function Species () {

    The prototype pattern diagrams of the two ones are illustrated.

    The past and present of JavaScript

     

    So it is because of this overridden effect that must pay attention to whether the prototype object is the original prototype object when you use this method.

    When you use this method, you must pay attention to whether the prototype object is the original prototype object.

    Both of the two have the advantages. How do they use the combination? What does the prototype chain have to do with the prototype?

    Look at the next chapter: , the past and present life of the prototype and prototype chain of JavaScript (two)

    The past and present of the prototype and prototype chain of JavaScript (two)

    Leave a Reply

    Your email address will not be published. Required fields are marked *