


Analysis of an interview question on javascript prototype chain (details)
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 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 Parent
You can directly output the answer on the console to get
11 [1,2,1] 5
This is surprising What’s confusing is why the last column of the array pointed to by this.b is
1 instead of
11?
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.
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():
-
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].
2. How to make the third item of the child1.__proto__.b array also output 11?
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.
Modify after instantiation
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:
-
If you understand the above explanation, then the same answer can be obtained here: 12 [1,2,1] 5##3.child2.show( )
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): 
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!
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];
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;
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).
child2.change()
Statements to the prototype object will affect the final output result of child1
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;
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).
child1.show():5 [1,2,1,11,12] 5
child2.show() :6 [1,2,1,11,12] 5
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):

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.
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!

JavaScript core data types are consistent in browsers and Node.js, but are handled differently from the extra types. 1) The global object is window in the browser and global in Node.js. 2) Node.js' unique Buffer object, used to process binary data. 3) There are also differences in performance and time processing, and the code needs to be adjusted according to the environment.

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Notepad++7.3.1
Easy-to-use and free code editor
