1. Where does constructor point to on the prototype object
Each function has a Prototype property, which is a reference to the function’s prototype object. Each prototype object has a constructor property, which points to the function object itself.
Verify:
function Fun(params) {}
console.log(Fun.prototype.constructor==Fun)//true
var a=new Fun();
console.log(a.__proto__.constructor===Fun)//true
Copy the code
2. Display versus implicit archetypes
First, we need to understand what the stereotype object does: it defines properties and methods shared by all object instances.
-
Each function has a prototype explicit property, which is just a reference to the prototype object
-
Each instance object has a __proto__, called an implicit prototype, which is also a reference. Eventually, it also points to the prototype object
The implicit prototype on the instance object has the same value as the prototype constructor corresponding to the instance; that is, the two different reference variable attributes point to the same block of address. All point to the prototype object
That is, in the chestnut below: the console outputs true
function Fun(params) {}var a=new Fun();
console.log(a.__proto__===Fun.prototype)
Copy the code
We can think of it as theta
- This statement is executed on new:
this.__proto__=Fun.prototype
It looks like this in memory:
3. Talk about prototypes and prototype chains
All the following concepts are my own understanding, if there is any mistake, please point out.
Prototype: Every function in JavaScript has a prototype property that holds a reference to an empty Object in memory. This Object is the function’s prototype Object and is used to share properties and variables. How to share? And that’s definitely using the concept of instance objects, where we instantiate this function, which in this case is also called a constructor, we instantiate multiple instance objects, so that all of our instances have access to properties or variables on our prototype object.
The first thing to know is two concepts: implicit prototype and __proto__. Implicit stereotypes are properties of instance objects, whereas explicit stereotypes are properties of functions. But the same thing is that they’re all a reference, and they don’t all point to the same block of memory, which is our prototype object.
Prototype Chains: Why are prototype chains called prototype chains? Simply because it is executed in a chained order of calls. In one sentence, it’s essentially looking for properties or methods along the implicit stereotype, so it’s also called the implicit stereotype chain. When we use an instance method to execute a property or method, we now assume that the desired property and method are in the prototype object. The order of execution in JavaScript memory is to look for the property or method in the prototype object via the __proto__ reference of the current instance. If the method does not have the property or method we are looking for, we continue in the __proto__ property of the current prototype Object into the memory referenced by __prote__, which is the prototype Object of the Object function (because we said earlier, The prototype property of each function refers to an empty Object instance, so there must be a __proto__ reference to the Object prototype. If it’s still not there, do some error handling. Because __proto__ is null in the prototype Object to which object. prototy points.
Next we can write some code to analyze its in-memory state:
function Fn() {
this.test1=function(){
console.log('test()')
}
Fn.prototype.test2=function(){
console.log('test2()')}}let fn=new Fn();
fn.test1();
fn.test2();
console.log(fn.toString())
console.log(fn.test3)
Copy the code
The graph in memory looks something like this
fn.test1()
The instance object has this method, so execute it directlyfn.test2()
, first look in the sample object, find no, and then pass__proto__
This property is found in the prototype object. performfn.toString()
, according to the previous step, find the prototype object found does not have this property, then in__proto__
To find, find, and execute a prototype objectfn.test3
After finding the prototype Object of Object, and finding that there is still no Object, enter the implicit prototype of Object, where it has reached the end, soundefined
There are actually two things we can take note of:
- **Object prototype objects are not Object sample objects: ** Display prototypes of functions default to point to instance objects of one Object at a time. One special exception, however, is the instance Object to which the Prototype property of Object itself points, because its implicit Prototype property points to NULL.
- At the end of the prototype chain is the prototype Object of Object, because its implicit prototype is NULL
4. Relationship between Function, Object and prototype
Function is a relatively special Function because all functions are examples of Function, so the implicit prototype for each Function points to the prototype object of the Function.
The picture below is a very classic one. From the picture, we can see the following points:
-
All functions have two properties, explicit stereotypes (a sample Object pointing to Object) and implicit stereotypes (a prototype Object for Function).
-
Function is actually instantiating itself, so its implicit stereotype is executed, and therefore has its implicit stereotype equal to its explicit stereotype (this is a special case)
-
The Object Function is an example of Function, so we have object.__proto__ in the figure pointing to the example of function.protype. In fact, we can see this result because all functions are examples of Function, and Object is no exception
5. The prototype chain points to the topic
Now that you’ve seen this, why don’t you do some problems:
p.__proto__ // Person.prototype
Person.prototype.__proto__ // Object.prototype
p.__proto__.__proto__ //Object.prototype
p.__proto__.constructor.prototype.__proto__ // Object.prototype
Person.prototype.constructor.prototype.__proto__ // Object.prototype
p.__proto__.constructor // Person
Person.prototype.constructor // Person
Copy the code
6. Explore instanceOf
A instance B
First, let’s be clear about what instance does: Return true if B’s explicit prototype object is on A’s prototype chain
Interviewer: Write an instanceof by hand, young man!
Ok!
function instancof(left, right) {
let leftp = left.__proto__;// Get the left implicit prototype
let rightp = right.prototype;// Get a reference to right's explicit prototype object
// The search is over
while (true) {
if (leftp == null) {
false
}
if (leftp == rightp) {
return
true
}
leftp = leftp.__proto__
}
}
Copy the code
Writing an instance by hand is not difficult. Here are some questions to stimulate you:
console.log(Object instanceof Function)//true
console.log(Object instanceof Object)//true
console.log(Function instanceof Function)//true
console.log(Function instanceof Object)//true
function Foo(params) {}console.log(Object instanceof Foo);//false
Copy the code
Remember that the principle of instance is to determine whether the prototype of a function object is in the prototype chain of the previous example object, so we can easily write the principle and the result.
7. Two interview questions
The first line:
function A() {}
A.prototype.n=1;
var b=new A();
A.prototype={
n:2.m:3
}
var c=new A();
console.log(b.n,b.m,c.n,c.m)
Copy the code
Instantiate the object by placing an n attribute on the object. Instantiate the object with an n attribute. Next, A creates A new prototype object for its function object, assigns two properties and instantiates it. This instantiation refers to the prototype object, so our two sample objects refer to two different prototype objects
So the output is:
1 undefined 2 3
Copy the code
The second way:
function F() {}Object.prototype.a = function () {
console.log('a')}Function.prototype.b = function () {
console.log('b')}var f = new F();
f.a();
f.b();
F.a();
F.b();
Copy the code
ToString (); toString(); toString(); toString(); The second one adds a method to Function’s prototype object
F (): f (): f (): f (): f (): f (): f (): f (): f (); Function.prototype.__proto__-> object.prototype.a () F.b(): function.prototype.__proto__ -> object.prototype.a () F.b(): Each Function is an instance object of Function, so F as an instance object has its own prototype chain, and its implicit prototype points to the prototype object that Function’s display prototype points to