What is a prototype
Prototype is the basis of JavaScript inheritance, and JavaScript inheritance is based on prototype inheritance.
Each function we create has a Prototype attribute that points to an object that can contain shared properties and methods for all instances created by a particular type. So prototype is the prototype object of the object instance created by calling the constructor.
The advantage of using a prototype object is that all object instances can share its contained properties and methods.
Constructor, instance, stereotype object relationship
Each constructor has a prototype object and for each function there is a prototype property, which is an object.
Every prototype object has a pointer to the constructor and for every object, there’s a __proto__ pointer to the prototype object of the constructor.
Each instance is represented by a pointer to the prototype object
Proto is usually called an implicit prototype, and prototype is usually called an explicit prototype. You can say that an implicit prototype of an object points to an explicit prototype of the object’s constructor. Property methods defined on explicit stereotypes are passed to instances of the constructor through implicit stereotypes. This makes it easy for the instance to access the methods and properties on the constructor prototype.
function Foo() {};
const a = new Foo();
a.__proto__ === Foo.prototype; // true
Copy the code
Prototype chain
The Prototype mechanism is an internal link in an object that references other objects. If the desired attribute or method reference is not found on the current object, the engine continues along the prototype associated object, and so on. This series of links is called a prototype chain.
Object. Prototype is the top of the prototype chain, and its __proto__ still exists with a value of null
The constructor
Instance members and static members can be attached to constructors
Instance members: Instance members are members added inside the constructor via this. Instance members can only be accessed through the instantiated object. Static member: A member added to the constructor itself that can only be accessed through the constructor.
Function Star(name,age) {this.name = name; this.age = age; } // Static member star.sex = 'female '; Let stars = new Star(' red ',18); console.log(stars); // Star {name: "小红", age: 18} console.log(stars.sex); // undefined fails to access sex console.log(star.name); //Star cannot access instance member console.log(star.sex) directly through constructor; // The constructor provides direct access to static member copy codeCopy the code
extension
What happens to the process of new a new object?
- Create an empty object son {}
- Prepare the prototype link for the object son.proto = Father. Prototype
- Rebind this so that the constructor’s this points to the new object
- Assign a value to a new object property
- Return this, at which point the new object has the constructor’s properties and methods
Are methods shared for each instance created through constructors?
Not necessarily. There are two cases to discuss:
- Methods defined directly on constructors are not shared.
Function Star() {this.log = function () {console.log(' I love singing '); } this.name = 'leemo'; } let stu1 = new Star(); let stu2 = new Star(); stu1.sing(); // I like to sing stu2.sing(); // I love to sing console.log(stu1.sing === stu2.sing); // false console.log(stu1.name === stu2.name); // true copies the codeCopy the code
Stu1 and STU2 are two different instances pointing to different memory blocks. Each instance creates a new block of memory storage properties and methods.
If the attributes of the instance are primitive, there is no sharing problem, and the content of the specific values is the same.
- The method of adding through prototypes is shared.
function Star(name) { this.name = name; } star.prototype. Sing = function () {console.log(' I love singing ', this.name); }; Let stu1 = new Star(' stu1 '); Let stu2 = new Star(' stu2 '); stu1.sing(); // I love to sing. // I love to sing console.log(stu1.sing === stu2.sing); //true copies the codeCopy the code
Constructors Are functions assigned by stereotypes that are shared by all objects.
The rules for defining constructors are as follows: public properties are defined in constructors, and public methods are put on prototype objects.
Object and Function
Prototype is the root of all objects and nothing else.
Function prototype is a built-in Function from which all functions derive. The prototype of the built-in function object points to the root object.
Function.prototype.__proto__ === Object.prototype
Copy the code
Therefore, the connection between Object and Function is as follows: The default prototype of all functions is an Object instance, and the two are connected through the root Object.
Function and Object are both functions and objects. A = ‘a’,Object. A = ‘a’. They are functions because they are derived from “built-in function factories” and thus have the properties of functions. They are objects because they are derived from “root” objects and therefore have the characteristics of objects. Function.prototype points to “built-in functions”. Object. Prototype refers to “root Object”
It is now possible to understand the graph better:
Parent is both a Function and an Object, with __proto__ and prototype attributes. The native constructor Object and Function have both attributes
Parent, Object, Function as objects, __proto__ as functions. Prototype Person, Object, Function as functions, all have the prototype attribute, which is an Object. There’s the constructor property, there’s some properties and methods.
Parent.__proto__ === Fucntion.prototype
Object.__proto__ === Fucntion.prototype
Fucntion.__proto__ === Fucntion.prototype
p1.__proto__ === Parent.prototype
Copy the code
Take a function, for example
function fn(){}
fn.__proto__ === Function.prototype //true
fn instanceof Function //true
fn instanceof Object //true
Function.__proto__ === Function.prototype //true
Object.__proto__ === Function.prototype //true
fn.prototype.__proto__ === Object.prototype //true
fn.prototype.constructor === fn //true
Copy the code
Summary: Functions are both functions and objects, with __proto__ and prototype attributes. Prototype. Function. Prototype’s __proto__ attribute points to Object.prototype; Prototype eventually points to Object.prototype.
The end point of the prototype chain
Q1: Object.prototype.__proto__ === null. This is the end of the Javescript prototype chain.
Prototye === ‘Object’ typeof Object.prototye === ‘Object’ indicates that it is an Object of type, if it is generated by Object function, __proto__ === object.prototype. Then object.prototype. __proto__ points to itself, and the prototype chain made up of __proto__ attributes has no end. So in order for the prototype chain to end, Javascript says object.prototype.__proto__ === null.
Q2: The prototype attribute is a “Function “object, not an “object” object, so it has a __proto__ attribute. Function. Prototype. __proto__
Function.proto__ === function. prototype (); As a result, the same problem as Object appears, which is always recycled without end. __proto__ === object. prototype, object.prototype. __proto__ === null, is the end of the prototype chain. So there are two special cases at the end of the prototype chain.