define

JavaScript is often described as a prototype-based language — each object has a prototype object from which the object is a template and inherits methods and properties. A stereotype object may also have a stereotype from which it inherits methods and properties, layer by layer, and so on. This relationship, often referred to as the Prototype chain, explains why one object has properties and methods defined in other objects

— — MDN

__proto__withprototype

__proto__ is an attribute on every instance, and prototype is an attribute on the constructor.

For example

// Define a simple constructor
function aFn () {}
Copy the code

We then examine the prototype property of the constructor and print the following code on the console

Object.prototype.toString.call(aFn.prototype) 
// '[object Object]'

aFn.prototype
/ / {
//   constructor: ƒ aFn()
// [[Prototype]]: Object
// }

aFn.prototype.constructor === aFn
// true
Copy the code

The constructor aFn’s Prototype property is an object type. To be precise, the constructor aFn’s Prototype property refers to the constructor’s prototype object. The prototype object has a constructor property, which in turn refers back to the constructor aFn. (In later diagrams, however, we use AFN. prototype to represent the prototype object of the aFn constructor.)

Let me draw a simple diagram




Continue operations on the aFn

// Add the name attribute to the prototype object
aFn.prototype.name = 'aFn'
// Create an instance
const a1 = new aFn();
Copy the code

The new operator generates a new empty object a1 and adds a __proto__ attribute to a1, pointing to the constructor’s prototype object afn. prototype, which can be verified:

a1.__proto__ === aFn.prototype
// true
Copy the code




Object accesses the constructor’s prototype object via the __proto__ attribute. For example, a1 is an empty object, but a1. Name outputs aFn because A1 first looks for the name attribute in its own attribute. If it doesn’t, it accesses the prototypeobject through __proto__, and then looks for the name attribute in the prototypeobject. Return undefined. __proto__ connects prototype objects together, forming a prototype chain.

aFn.prototype
/ / {
//   constructor: ƒ aFn()
// [[Prototype]]: Object
// }
Copy the code

Constructor: ƒ Object() = ƒ Object() [[Prototype]] = __proto__[1]




[[Prototype]] refers to Object. Prototype. As shown in the figure, we draw all the Prototype chains including aFn




Prototype’s constructor property points to the Object constructor, which is the built-in method of JS. Object. Prototype as an Object, its __proto__ points to null, which is the end of any prototype chain.

In JavaScript, almost all objects are instances of type Object. They all inherit attributes and methods from Object.prototype, though most of the attributes are Shadowed or overridden. [2]

The Object constructor is something we don’t use very often. We usually create new objects using literal syntax:

var obj = {} // Literal syntax
obj.__proto__ === Object.prototype // true

//
var o = new Object()
o.__proto__ === Object.prototype // true
Copy the code

Stereotypes and stereotype chains in built-in objects

JavaScript has a standard library of built-in objects, and there are common types of JavaScript built-in objects: Object, Number, Array, String, Function, and so on.

According to the experiment:

Symbol.prototype.__proto__ === Object.prototype // true
Number.prototype.__proto__ === Object.prototype // true
String.prototype.__proto__ === Object.prototype // true
Array.prototype.__proto__ === Object.prototype  // true
Date.prototype.__proto__ === Object.prototype   // true
RegExp.prototype.__proto__ === Object.prototype // true
Map.prototype.__proto__ === Object.prototype    // true
Set.prototype.__proto__ === Object.prototype    // true
Promsie.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Copy the code

Prototype is an Object type. Objects are instances of Object.prototype.




Let’s look at the Function type [3]

For example, we use the Function constructor to generate a Function

var bFn = new Function('console.log(1234)');
bFn() / / 1234
Object.prototype.toString.call(bFn) // [object Function]
bFn.prototype.__proto__ === Object.prototype // true
Copy the code

The new operator generates an object, so this bFn is also an object type. so

bFn.__proto__ === Function.prototype // true
Copy the code

The same goes for function declarations, function expressions, and so on

functoin a() {}
a.__proto__ === Function.prototype // true

var b= function () {}
b.__proto__ === Function.prototype // true

var c = () = > {}
c.__proto__ === Function.prototype // true
Copy the code

The same goes for the constructor for the built-in object:

Array.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype // true
Number.__proto__ === Function.prototype // true
Date.__proto__ === Function.prototype   // true
Symbol.__proto__ === Function.prototype // true
// The same goes for the Object constructor
Object.__proto__ === Function.prototype // true
Copy the code

Every JavaScript Function is actually a Function object [3]

Built-in functions can be thought of as instance objects of the Function constructor, but there is one in particular

Function.__proto__ === Function.prototype // true
Copy the code

Function’s __proto__ also points to function. prototype, and the prototype property of the Function constructor also points to function. prototype




The red line here points to function.prototype

reference

  • [1] [[Prototype]]
  • [2] Object
  • [3] Function