Here we discuss the relationship between the object's internal prototype (__proto__) and the constructor's prototype (prototype).
1. The __proto__ of all constructors/functions points to Function.prototype, which is an empty function (Empty function)
Number.__proto__ === Function.prototype // true
Boolean.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Array.__proto__ === Function. prototype // true
RegExp.__proto__ === Function.prototype // true
Error.__proto__ === Function.prototype // true
Date.__proto__ === Function.prototype // true
There are a total of 12 built-in constructors/objects in JavaScript (JSON is newly added in ES5). Here are 8 accessible constructors. The rest such as Global cannot be accessed directly, Arguments are only created by the JS engine when the function is called, Math and JSON exist in the form of objects and do not require new. Their __proto__ is Object.prototype. As follows
Math.__proto__ === Object.prototype // true
JSON.__proto__ === Object.prototype // true
The "all constructors/functions" mentioned above certainly include custom ones. As follows
// Function declaration
function Person() {}
// Function expression
var Man = function() {}
console.log(Person.__proto__ === Function.prototype) // true
console.log(Man. __proto__ === Function.prototype) // true
What does this mean?
All constructors come from Function.prototype, even the root constructor Object and Function itself. All constructors inherit the properties and methods of Function.prototype. Such as length, call, apply, bind (ES5).
Function.prototype is also the only prototype whose typeof XXX.prototype is "function". The prototype of other constructors is an object. As follows
console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype) // object
console.log(typeof Number.prototype) // object
console.log(typeof Boolean.prototype) // object
console .log(typeof String.prototype) // object
console.log(typeof Array.prototype) // object
console.log(typeof RegExp.prototype) // object
console.log(typeof Error .prototype) // object
console.log(typeof Date.prototype) // object
console.log(typeof Object.prototype) // object
Oh, it’s also mentioned above It turns out that it is an empty function, look at alert(Function.prototype).
We know that the __proto__ of all constructors (including built-in and custom) are Function.prototype, so who is the __proto__ of Function.prototype?
I believe you have heard that functions in JavaScript are also first-class citizens, so where can you show this? As follows
console.log(Function.prototype.__proto__ == = Object.prototype) // true
This shows that all constructors are also ordinary JS objects, and you can add/remove attributes to the constructor. At the same time, it also inherits all methods on Object.prototype: toString, valueOf, hasOwnProperty, etc.
Who is the __proto__ of Object.prototype?
Object.prototype.__proto__ === null // true
has reached the top and is null.
2. The __proto__ of all objects points to the prototype of its constructor
The __proto__ of all built-in constructors and custom constructors have been tested above. Let’s take a look at the __proto__ of all the instance objects of these constructors. Who does _proto__ point to?
Let’s take a look at the built-in constructor of the JavaScript engine first
var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = new Date
var err = new Error('exception')
console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype) // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype) // true
console.log(err.__proto__ === Error.prototype) // true
Look at the custom constructor again, a Person is defined here
function Person(name) {
this.name = name
}
var p = new Person('jack ')
console.log(p.__proto__ === Person.prototype) // true
p is an instance object of Person, and the internal prototype of p always points to its constructor Person. prototype.
Each object has a constructor attribute that can get its constructor, so the following printed results are also identical
function Person(name) {
this.name = name
}
var p = new Person('jack')
console .log(p.__proto__ === p.constructor.prototype) // true
The Person above does not add attributes or methods to its prototype. Here, add a getName method to its prototype
function Person(name) {
this.name = name
}
// Modify prototype
Person.prototype.getName = function() {}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true
You can see p.__proto__ and Person.prototype, p.constructor.prototype are all identical, that is, they all point to the same object.
If you set up the prototype in another way, the results will be a little different
function Person(name) {
this.name = name
}
// Override prototype
Person.prototype = {
getName: function() {}
}
var p = new Person('jack')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p. constructor.prototype) // false
Person.prototype is directly rewritten here (note: the previous example is to modify the prototype). The output shows that p.__proto__ still points to Person.prototype, not p.constructor.prototype.
This is also easy to understand. What is assigned to Person.prototype is an object literal {getName: function(){}}. The constructor of an object defined using the object literal method points to the root constructor. Object, Object.prototype is an empty object {}, {} is naturally different from {getName: function(){}}. As follows
var p = {}
console.log (Object.prototype) // It is an empty object {}
console.log(p.constructor === Object) // The constructor of an object defined in the object literal mode is Object
console.log(p .constructor.prototype === Object.prototype) // If true, no explanation is given
The __proto__ used in the above code is currently not supported in IE6/7/8/9. In IE9, you can use Object.getPrototypeOf(ES5) to get the internal prototype of an object.
var p = {}
var __proto__ = Object .getPrototypeOf(p)
console.log(__proto__ === Object.prototype) // true