In JavaScript, there is a "famous" triangular relationship between prototype, constructor and __proto__. Let me lead you to explain these relationships in detail.
There are many and confusing relationships in JavaScript. The scope chain is a one-way chain relationship, which is relatively simple and clear; the calling relationship of this mechanism is slightly complicated; and regarding the prototype, it is the triangular relationship between prototype, proto and constructor. This article first uses a picture to make the concept clear, and then explains in detail the triangular relationship of the prototype
Illustration
Concept
The complexity in the picture above The relationship, in fact, 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 through 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 attribute that points to the prototype object of the instance object. Multiple objects instantiated through the same constructor have the same prototype object. Prototype objects are often used 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 attribute that points to the constructor corresponding to the prototype object
function Foo(){}; console.log(Foo.prototype.constructor === Foo);//true
Since instance objects can be inherited Attributes of the prototype object, so the instance object also has a constructor attribute, which also points to the constructor 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, pointing to the corresponding constructor of the instance object Prototype object
function Foo(){}; var f1 = new Foo; console.log(f1.__proto__ === Foo.prototype);//true
Description
The concept is introduced, now let’s explain the relationship in detail
function Foo(){}; var f1 = new Foo;
[Part 1: Foo]
The instance object f1 is created through the new operation of the constructor Foo(). The prototype object of the constructor Foo() is Foo.prototype; the instance object f1 also points to the prototype object Foo.prototype
function Foo(){}; var f1 = new Foo; console.log(f1.__proto === Foo.prototype);//true
through the __proto__ attribute. The instance object f1 itself does not have a constructor attribute, but it can inherit the prototype object The constructor property of Foo.prototype
function Foo(){}; var f1 = new Foo;console.log(Foo.prototype.constructor === Foo);//true console.log(f1.constructor === Foo);//true console.log(f1.hasOwnProperty('constructor'));//false
The following picture is 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. Therefore, Foo.prototype is an instance object, its constructor is Object(), and the prototype object is Object.prototype. Correspondingly, the prototype attribute of the constructor Object() points to the prototype object Object; the proto attribute 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);//true
The instance object Foo.prototype itself has the constructor attribute, so it will override The constructor property 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 used as an instance object, its prototype object What is, the result is null. I personally think that this may be one of the reasons why the result of typeof null is 'object'
console.log(Object.prototype.__proto__ === null);//true
[Part 3: Function]
As mentioned before As mentioned before, functions are also objects, but they are objects with special functions. Any function can be regarded as the result of instantiation through the new operation of the Function() constructor
If 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);//true console.log(Object.__proto__ === Function.prototype);//true
. The constructor property of the prototype object Function.prototype points to the constructor Function(); the instance objects Object and Foo themselves do not have The constructor attribute needs 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 regarded as instantiated objects of the new operation of the constructor function Function(). Then, Function can be regarded as the instantiation result of calling its own new operation
Therefore, if Function is used as an instance object, its constructor is 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 used as an instance object, what is its prototype object? As before, all objects can be regarded as the instantiation results 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
As introduced in the second part, the prototype object of Object.prototype is null
console.log(Object.prototype.__proto__ === null);//true
总结
【1】函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype
【2】对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype
【3】Object.prototype的原型对象是null
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of Illustration of the triangular relationship between prototype, proto and constructor. For more information, please follow other related articles on the PHP Chinese website!