Home  >  Article  >  Web Front-end  >  Analysis of an interview question on javascript prototype chain (details)

Analysis of an interview question on javascript prototype chain (details)

不言
不言Original
2018-09-19 17:12:065602browse

The content of this article is an analysis (detailed) of an interview question about the JavaScript prototype chain. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

In the face of the basics, all skills are in vain.

The question is like this

Requires writing the output of the console.

function Parent() {
            this.a = 1;
            this.b = [1, 2, this.a];
            this.c = { demo: 5 };
            this.show = function () {
                console.log(this.a , this.b , this.c.demo );
            }
        }
function Child() {
    this.a = 2;
    this.change = function () {
        this.b.push(this.a);
        this.a = this.b.length;
        this.c.demo = this.a++;
    }
}
        Child.prototype = new Parent(); 
        var parent = new Parent();
        var child1 = new Child();
        var child2 = new Child();
        child1.a = 11;
        child2.a = 12;
        parent.show();
        child1.show();
        child2.show();
        child1.change();
        child2.change();
        parent.show();
        child1.show();
        child2.show();

The knowledge points involved in the question

  • this Points to

  • Prototype machine prototype chain

  • Inheritance of class

  • Primitive type and reference type Difference
    Each knowledge point can be taken out for separate special research.

Details of knowledge points needed to solve the problem

1. Constructors have a prototype attribute, pointing to the prototype object of the constructor, and the instances will share the same A prototype object;

2. When an instance is generated, a new heap memory will be generated in the memory. General operations on the instance will not affect other instances, because they occupy different spaces in the heap memory and do not affect each other. ;

3. Each instance has an implicit prototype __proto__ that points to the prototype object of the constructor;

4.This pointing problem, common situations include the following:

4.1 When used as an object method, it points to whoever calls it (this question mainly involves this)

4.2 When called as a function, it points to the global top-level variable window

4.3 As a constructor When a function is called, that is, when the new operator generates an instance, this in the constructor points to the instance

4.4 In the call and apply methods, the binding of the specified this is displayed as the specified context

5. Literal Quantitative method (there is also information that translates literal into direct quantity. I personally think that the latter translation is actually more intuitive and more vivid). When assigning objects and arrays (the essence of arrays is also objects), they are all references, that is, resources are generated in the heap memory. The stack memory generates variables, and then the variables point to the address of the resource.

6. The search rules of the prototype chain follow the shortest path principle, that is, first search for the instance attributes, and then search for the specified attributes along the prototype chain until Object.prototype and null at the end of the prototype chain. If the instance itself and If the property being searched does not exist in the entire prototype chain, undefined will be returned

7. The detailed difference between assignment statements for primitive value assignment and reference type assignment.

Start analyzing the question

1.parent.show()

There is basically nothing to explain.
You can get the answer by directly taking the value1 [1,2,1] 5;

2.child1.show()# The constructor of

##Child was originally pointing to Child. In the question, Child
is explicitly set to The prototype object of the class points to an instance of the Analysis of an interview question on javascript prototype chain (details)Parent
class, which is one of the common inheritance methods in JavaScript object-oriented programming. It should be noted here that Child.prototype points to the instance Parent, not to the class ParentYou can directly output the answer on the console to get11 [1,2,1] 5
Analysis of an interview question on javascript prototype chain (details)
This is surprising What’s confusing is why the last column of the array pointed to by this.b is 1 instead of
11Analysis of an interview question on javascript prototype chain (details)?

Let’s first take a look at what child1 looks like: When the child1.show() method is executed, since child1, as an instance of Child, has the attribute a, so this.a in the show() method will directly point to the value of this attribute, also It is 11, and will not continue along the prototype chain to get the a attribute on the object pointed to by __proto__;

Then look for this.b. Since child1 does not have the attribute b, it will go along the prototype chain. Get the b attribute on parent, its value is an array, the first two items are constants, nothing to say, the last item of the array is a reference, and the pointer here is not a dynamic pointer, because in new Parent() In one step, it has been executed once, and it is determined to point to the resource pointed by parent.a, which is the resource pointed to by the a attribute in child1.__proto__, which is the value 1.
Analysis of an interview question on javascript prototype chain (details)

Extended Thoughts

It should be noted that:

From the code point of view, the child1.__proto__.b array The three items point to child1.__proto__.a. If we modify the value of child1.__proto__.a at this time, will it affect the result of child1.show():

  1. The answer is that it has no impact. Why do properties that seem to point to the same address have different values? Because when the parent instance is generated, this.a points to a primitive value 2, so the third item in this.b is actually assigned a primitive value, so it looks like a reference type assignment at first glance, but it is not. . Primitive value assignment will open up new storage space, making the values ​​​​of this.a and this.b[2] equal, but pointing to different addresses in the heap memory. For more detailed explanations, please see the blog posts recommended in [Extended Reading].

    Analysis of an interview question on javascript prototype chain (details)

    2. How to make the third item of the child1.__proto__.b array also output 11?


    Modify after instantiation

    Because in In the Parent class definition, the third item of the b attribute array points to the value of the a attribute, which means that this reference is dynamically pointed to before the Parent is instantiated, so as long as the value of this.a in the class definition is changed before the Parent is instantiated, , you can achieve the desired effect. If it has been instantiated in Parent, you can only explicitly modify the value of the *.b[2] attribute.
get/set method synchronization

Another way is to set the get/set method for the a attribute. Yes, whenever the value of the a attribute changes, the value of b[2] is modified synchronously. The code and running results are as follows:



  • Analysis of an interview question on javascript prototype chain (details)##3.child2.show( )
    Analysis of an interview question on javascript prototype chain (details)

    If you understand the above explanation, then the same answer can be obtained here: 12 [1,2,1] 5
Then the code is executed: child1.change(); child2.change();

4.parent.show()

parent is an instance of the Parent class, and Child.prorotype points to another instance of the Parent class. The two are two resources in the heap memory and do not affect each other. Therefore, the above operations do not affect the parent instance.

The output results remain Unchanged: 1 [1,2,1] 5;
5.child1.show(),child2.show()

What changes happened after child1 executed the change() method?

this.b.push(this.a)
Due to the dynamic pointing characteristics of this, this.b will point to the b array on Child.prototype, and this.a will point to the a attribute of child1, so Child.prototype.b becomes It becomes [1,2,1,11];

this.a = this.b.length
The points of this.a and this.b in this statement are the same as The previous sentence is consistent, so the result is that child1.a becomes 4;

this.c.demo = this.a
Because child1’s own attributes do not have c attribute, so this.c here will point to Child.prototype.c. The value of this.a is 4, which is a primitive type. Therefore, the value will be assigned directly during the assignment operation, Child.prototype.c. The result of demo is 4, and this.a then increases to 5(4 1 = 5).

Then, child2 executes the change() method, Both child2 and child1 are instances of the Child class, so their prototype chains point to the same prototype object Child.prototype, which is the same parent instance, So all the effects in child2.change() Statements to the prototype object will affect the final output result of child1

this.b.push(this.a)

Because The dynamic pointing feature of this, this.b will point to the b array on Child.prototype, this.a will point to the a attribute of child2, so Child.prototype.b becomes

[1,2,1, 11,12];

this.a = this.b.length
The directions of this.a and this.b in this statement are consistent with the previous sentence, so the result is child2.a becomes 5;

this.c.demo = this.a
Since child2’s own attribute does not have the c attribute, this.c here will point to Child.prototype.c, so the execution result is that the value of Child.prototype.c.demo becomes the value of child2.a, 5, and child2.a eventually increments to 6 (5 1 = 6).

Next, execute the output command, and the final result will be output:
child1.show():5 [1,2,1,11,12] 5
child2.show() :6 [1,2,1,11,12] 5

Extended thinking
When I was solving the problem, I made an error in this.c.demo = this.a. I thought there would be something wrong here. A reference is passed, but a value is actually passed. After analysis, it is understood that because this.a points to an original value, it is equivalent to assigning the original value to the object attribute, so the value of child.c.demo will not be affected after the assignment. The impact of changes to child.a. If child.a is a reference type, what will the result look like?
We make some modifications to the source code and point child.a to an object (i.e. reference type): Analysis of an interview question on javascript prototype chain (details)
Then after running, we will find that the value of Child.prototype.c will follow the value of child1.a Changes with changes, because the value of child1.a is a reference type at this time, and the assignment process will make Child.prototype.c and child1.a point to the memory space address of the same resource. For a more detailed explanation of original types and reference types, you can refer to the blog in Extended Reading at the end of this article.

Harvest and Reflection

1. Basic knowledge is originally scattered details, and must be learned with the mentality of fighting to the end.

2. Basic knowledge is the most boring thing, and it is also what really widens the gap between people. It is also the threshold that you must cross if you want to enter a big factory. It is important but not urgent. We are also novices. Some people will become front-end architects after 3-5 years. Some people will still use endless new frameworks to bind events to buttons after 3-5 years. Whoever you want to be depends on how much effort you have to put in. , most of the time there is nothing wrong with it. The foundation is very important! Very important! Very important!

The above is the detailed content of Analysis of an interview question on javascript prototype chain (details). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn