There's a lot of chaos in the JavaScript relationship. The scope chain is a one-way chain relationship, which is simple and clear; the invocation relationship of this mechanism is somewhat complicated, while the prototype is the triangular relationship between prototype, Proto and constructor. This article first uses a diagram to begin with, and then explains the triangular relationship of the prototype in detail.
Icon
Concept
The complex relationship in the diagram above actually comes from two lines of code
function foo () {};var f1 = new Foo;
"Constructor"
The function used to initialize the newly created object is the constructor. In the example, the Foo () function is the constructor
"Instance Object"
The object created by the new operation of the constructor is an instance object. You can use a constructor to construct multiple instance objects
function Foo () {};
var f1 = new Foo;
var F2 = new Foo;
Console.log (f1 = = = F2);//false
"Archetypal objects and prototype"
The constructor has a prototype property that points to the prototype object of the instance object. Multiple objects instantiated with the same constructor have the same prototype object. Always use a prototype object to implement inheritance
function Foo () {};
Foo.prototype.a = 1;
var f1 = new Foo;
var F2 = new Foo;console.log (FOO.PROTOTYPE.A);
1
console.log (f1.a);//1
Console.log (f2.a);//1
"Constructor"
The prototype object has a constructor property that points to the corresponding constructor of the prototype object
function Foo () {};
Console.log (Foo.prototype.constructor = = = Foo);//true
Because the instance object can inherit the properties of the prototype object, the instance object also owns the constructor property and also points to the constructor for the prototype object
function Foo () {};
var f1 = new Foo;
Console.log (F1.constructor = = = Foo);//true
"Proto"
The instance object has a Proto property that points to the prototype object corresponding to the instance object
function Foo () {};
var f1 = new Foo;
Console.log (f1.__proto__ = = = Foo.prototype);//true
Description
After the introduction of the concept, the relationship between the diagrams is now described in detail
function Foo () {};
var f1 = new Foo;
"First part: Foo"
The instance object F1 is created by the new operation of the constructor foo (). The prototype object of the constructor foo () is Foo.prototype, and the instance object F1 also points to the prototype object through the __proto__ property Foo.prototype
function Foo () {};
var f1 = new Foo;
Console.log (F1.__proto = = = Foo.prototype);//true
The instance object F1 itself does not have a constructor property, but it can inherit the constructor properties of the prototype object Foo.prototype
function Foo () {};
var f1 = new Foo;console.log (Foo.prototype.constructor = = foo);//true
console.log (f1.constructor = = foo);//true< C10/>console.log (F1.hasownproperty (' constructor '));//false
The following figure is the console effect of the instance object F1
"Part Two: Object"
Foo.prototype is a prototype object of F1, and it is also an instance object. In fact, any object can be considered an object that is instantiated through the new operation of the object () constructor so, Foo.prototype as an instance object, its constructor is object (), and the prototype object is Object.prototype. Correspondingly, the prototype property of the constructor object () points to the prototype object; The Proto property of the instance object Foo.prototype also points to the prototype object
function Foo () {};
var f1 = new Foo;
Console.log (foo.prototype.__proto__ = = = Object.prototype);//true
The instance object Foo.prototype itself has a constructor property, so it overrides the constructor attribute inherited from the prototype object Object.prototype
function Foo () {};
var f1 = new Foo;
Console.log (Foo.prototype.constructor = = Foo);//true
console.log (Object.prototype.constructor = = Object);// True
Console.log (Foo.prototype.hasOwnProperty (' constructor '));//true
The following figure is the console effect of the instance object Foo.prototype
If Object.prototype is an instance object, what is its prototype object, and the result is null. Privately, this may also be one of the reasons that typeof Null's result is ' object '.
Console.log (object.prototype.__proto__ = = null);//true
"Part III: Function"
As already mentioned, functions are objects, but only objects with special functions. Any function can be viewed as a result of the instantiation of the new operation of the function () constructor
If the function foo is an instance object, its constructor is a function () whose prototype object is Function.prototype; Similarly, the constructor of the function object is also a function (). Its prototype object is Function.prototype
function Foo () {};
var f1 = new Foo;console.log (foo.__proto__ = = function.prototype)//true
console.log (object.__proto__ = = Function.prototype);//true
The constructor attribute of the prototype object Function.prototype to the constructor function function (), and the instance object and Foo itself have no constructor properties. Need to inherit the constructor attribute of the prototype object Function.prototype
function Foo () {};
var f1 = new Foo;
Console.log (Function.prototype.constructor = = function);//true
console.log (foo.constructor = = function);// True
Console.log (Foo.hasownproperty (' constructor '));//false
console.log (object.constructor = = Function) ;//true
Console.log (Object.hasownproperty (' constructor '));//false
All functions can be considered as instantiated objects of the new operation of the constructor function (). So, a function can be seen as the result of an instantiation of the new operation calling itself.
So, if a function is an instance object, its constructor is a function, and its prototype object is Function.prototype
Console.log (function.__proto__ = = Function.prototype);//true
console.log (Function.prototype.constructor = = function);//true
console.log (Function.prototype = = function);//true
If Function.prototype is an instance object, what is its prototype object? As before, all objects can be viewed as instantiated results of the new operation of the object () constructor. So, the prototype object of Function.prototype is Object.prototype, whose prototype function is Object ()
Console.log (function.prototype.__proto__ = = = Object.prototype);//true
The second part describes that the prototype object of Object.prototype is null
Console.log (object.prototype.__proto__ = = null);//true
Summarize
The "1" function, which is also a function, is the result of the new function, so the function can be an instance object whose constructor is a function () and the prototype object is Function.prototype
The "2" object (the function is also the object) is the result of the new object, so the object can be an instance object, its constructor is object (), and the prototype object is Object.prototype
The prototype object of the "3" Object.prototype is null