There are many and chaotic relationships in JavaScript. The scope chain is a one-way chain relationship, which is quite simple and clear; the calling relationship of this mechanism is a bit complicated; and as for the prototype, it is a triangular relationship between prototype, proto and constructor. This article first uses a picture to clarify the meaning, and then explains the triangle relationship of the prototype in detail.
Illustration
concept
The complex relationship in the above picture 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 a constructor
【Instance Object】
The object created by the new operation of the constructor is an instance object. You can use one constructor to construct multiple instance objects
function Foo(){};var f1 = new Foo;var f2 = new Foo;console.log(f1 === f2);//false【Prototype Objects and Prototype】
The constructor has a prototype property that points to the prototype object of the instance object. Multiple objects instantiated by the same constructor have the same prototype object. Regularly use prototype objects to achieve inheritance
function Foo(){};Foo.prototype.a = 1;var f1 = new Foo;var f2 = new Foo;console.log(Foo.prototype.a);//1console.log(f1.a);//1console.log(f2.a);//1console.log(f2.a);//1【constructor】
The prototype object has a constructor attribute that points to the constructor function corresponding to the prototype object.
function Foo(){};console.log(Foo.prototype.constructor === Foo);//trueSince the instance object can inherit the properties of the prototype object, the instance object also has the constructor attribute, which also points to the constructor function corresponding to the prototype object.
function Foo(){};var f1 = new Foo;console.log(f1.constructor === Foo);//true【proto】
The instance object has a proto attribute that points to the prototype object corresponding to the instance object
function Foo(){};var f1 = new Foo;console.log(f1.__proto__ === Foo.prototype);//trueillustrate
The concept has been introduced, and now we will explain the relationship in detail.
function Foo(){};var f1 = new Foo;【Part 1: 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; instance object f1 also points to the prototype object Foo.prototype through the __proto__ attribute.
function Foo(){};var f1 = new Foo;console.log(f1.__proto === Foo.prototype);//trueThe instance object f1 itself does not have a constructor attribute, but it can inherit the constructor attribute of the prototype object Foo.prototype.
function Foo(){};var f1 = new Foo;console.log(Foo.prototype.constructor === Foo);//trueconsole.log(f1.constructor === Foo);//trueconsole.log(f1.hasOwnProperty('constructor'));//falseThe following figure shows the console effect of the instance object f1
【Part 2: Object】
Foo.prototype is the prototype object of f1, and it is also an instance object. In fact, any object can be regarded as an object instantiated through the new operation of the Object() constructor. So, Foo.prototype is an instance object, its constructor is Object() and the prototype object is Object.prototype. Accordingly, the prototype property of the constructor Object() points to the prototype object Object; the proto property of the instance object Foo.prototype also points to the prototype object Object
function Foo(){};var f1 = new Foo;console.log(Foo.prototype.__proto__ === Object.prototype);//trueThe instance object Foo.prototype itself has the constructor attribute, 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);//trueconsole.log(Object.prototype.constructor === Object);//trueconsole.log(Foo.prototype.hasOwnProperty('constructor'));//trueconsole.log(Foo.prototype.hasOwnProperty('constructor'));//trueThe following figure shows the console effect of the instance object Foo.prototype
If Object.prototype is an instance object, what is its prototype object? The result is null. I think this may also be the result of typeof null, which is one of the reasons why 'object'
console.log(Object.prototype.__proto__ === null);//true
【Part 3: Function】
As mentioned earlier, functions are objects, but objects with special functions. Any function can be regarded as the result of instantiation through the new operation of the Function() constructor.
If the function Foo is regarded as an instance object, its constructor is Function() and its prototype object is Function.prototype; similarly, the constructor of the function Object is also Function(), and its prototype object is Function.prototype.
function Foo(){};var f1 = new Foo;console.log(Foo.__proto__ === Function.prototype);//trueconsole.log(Object.__proto__ === Function.prototype);//trueThe constructor attribute of the prototype object Function.prototype points to the constructor function(); the instance object Object and Foo do not have the constructor attribute, and it is necessary to inherit the constructor attribute of the prototype object Function.prototype.
function Foo(){};var f1 = new Foo;console.log(Function.prototype.constructor === Function);//trueconsole.log(Foo.constructor === Function);//trueconsole.log(Foo.hasOwnProperty('constructor'));//falseconsole.log(Object.constructor === Function);//trueconsole.log(Object.hasOwnProperty('constructor'));//falseAll functions can be regarded as instantiated objects of the new operation of the constructor Function(). Then, Function can be regarded as the result of calling its own new operation instantiation.
So, if Function is an instance object, its constructor is Function, and its prototype object is Function.prototype
console.log(Function.__proto__ === Function.prototype);//trueconsole.log(Function.prototype.constructor === Function);//trueconsole.log(Function.prototype === Function);//trueconsole.log(Function.prototype === Function);//true
If Function.prototype is an instance object, what is its prototype object? As before, all objects can be regarded as the instantiation result of the new operation of the Object() constructor. Therefore, the prototype object of Function.prototype is Object.prototype, and its prototype function is Object()
console.log(Function.prototype.__proto__ === Object.prototype);//true
The second part introduces that the prototype object of Object.prototype is null
console.log(Object.prototype.__proto__ === null);//true
Summarize
【1】The function (Function is also a function) is the result of a new function, so the function can be used as an instance object, its constructor is Function(), and the prototype object is Function.prototype
【2】Objects (functions are also objects) are the result of new Object, so the object can be used as an instance object, its constructor is Object(), and the prototype object is Object.prototype
【3】Object.prototype's prototype object is null