This time I will give you a brief analysis of the relationship between __proto__ and prototype in JavaScript. The following is a practical case. Follow the editor to take a look.
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 (build-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 Person() {} // 函数表达式 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 typeof XXX.prototype prototype of "function". The prototype of other constructors is an object. For example:
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 was also mentioned above that it is an empty function, let’s take a look at alert(Function.prototype).
Now that we know that the __proto__ of all constructors (including built-in and custom) are Function.prototype, then who is the __proto__ of Function.prototype?
I believe you have all heard that functions in JavaScript are also first-class citizens, so how can you show this? As shown below
console.log(Function.prototype.__proto__ === Object.prototype) // true
This shows that all constructors are also ordinary JS objects, and attributes can be added/removed 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 above tests the __proto__ of all built-in constructors and custom constructors, below Let’s take a look at who the __proto__ of the instance objects of all these constructors points to?
Let’s first look at the built-in constructor of the JavaScript engine
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
Then look at the custom constructor. 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, p The internal prototype always points to the prototype of its constructor Person.
Each object has a constructor attribute, and its constructor can be obtained, so the following print results are also identical
function Person(name) { this.name = name } var p = new Person('jack') console.log(p.__proto__ === p.constructor.prototype) // true
The above Person does not add attributes or methods to its prototype, here Add a getName method to its prototype
function Person(name) { this.name = name } // 修改原型 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 that p.__proto__, Person.prototype, and p.constructor.prototype are all identical, that is, they all point to the same object.
If you set the prototype in another way, the result will be somewhat different
function Person(name) { this.name = name } // 重写原型 Person.prototype = { getName: function() {} } var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // false
Here, Person.prototype is directly rewritten (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 object literals points to the root constructor Object, Object.prototype is an empty object {}, {} is naturally the same as {getName: function(){}} is not equal. As follows
var p = {} console.log(Object.prototype) // 为一个空的对象{} console.log(p.constructor === Object) // 对象直接量方式定义的对象其constructor为Object console.log(p.constructor.prototype === Object.prototype) // 为true,不解释
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
The above is the detailed content of A brief analysis of the relationship between __proto__ and prototype in JavaScript. For more information, please follow other related articles on the PHP Chinese website!