1. Introduction
Talking about prototypes involves constructors, classes, and so on. I’ll leave that for later extensions. If you’re not clear, look at the extensions first
This article is to find some information (article) after reading the summary, some places may not understand very deep, there are mistakes must help me to point out, thank you very much ~ recently in the “you don’t know Javascript”, after seeing the content of the prototype will be updated ==
2. Prototypes and prototype chains
Before we get started, remember this:
- object:
__proto__
andconstructor
Properties;__proto__
andconstructor
objectUnique.
- function:
prototype
,__proto__
andconstructor
Properties;prototype
isfunctionThe unique;- Since functions in JS are also objects, so are functions
__proto__
andconstructor
Properties.
- All reference types in JS are objects
prototype
,__proto__
andconstructor
Properties; - Note:
[[Prototype]]
and__proto__
It’s the same thing: both represent “connections” in the prototype chain. Used in the JavaScript language standard[[prototype]]
(officially), and__proto__
Is provided by many browsers (unofficially);
2.1. The prototypeprototype
prototype
isfunctionThe unique;- A prototype is an object
The function prototype.
Access; - Prototype usually has two properties:
__proto__
andconstructor
; - Prototypes can be used to share methods;
- The reference to this in the prototype is the instance.
2.2. Implicit archetypes__proto__
__proto__
isobjectThe unique;- Object through
__proto__
To access the parent constructor prototype:Object.__proto__ === parent constructor. Prototype
.
2.3. The constructorconstructor
constructor
isobjectThe unique;- Object’s constructor points to the constructor property on the parent constructor stereotype:
Constructor === parent constructor. Prototype.constructor
.- In general, constructor of a constructor prototype refers to the constructor itself, i.e.
Constructor === parent constructor. Prototype. constructor === parent constructor
(See special casesConstructor can be lost); - Note: When there is no constructor property in the parent constructor stereotype, the constructor of the constructor stereotype at the next level up will be found through the stereotype chain (see Constructor may be missing).
- In general, constructor of a constructor prototype refers to the constructor itself, i.e.
Note: Constructor can be lost
function Person(name) {
this.name = name;
}
Person.prototype = {};
const p = new Person('p');
p.name; // p
Person.prototype; // {} constructor attribute missing!
// constructor of instance p is not a Person!
p.constructor === Person; // false
// Look above Person
p.constructor === Person.prototype.__proto__.constructor // true
Person.prototype.__proto__.constructor === Object // true
p.constructor === Object // true
Copy the code
In the example above, Person. Prototype is assigned to an empty object, and Person itself has no constructor property. Constrctor refers to person.prototype.__proto__. Constructor, which is Object. The constructor property of instance P also points to Object.
Constructor = constructor = constructor
Person.prototype.constructor = Person;
Copy the code
2.4. The prototype chain
We already know about the prototype and the implicit __proto__
An instance that can access the parent constructor’s prototype via __proto__; Prototypes can also be accessed by __proto__ the prototype of the prototype. When you call a method on an instance, you look for that method, starting with the instance itself. If the instance itself does not have one, the parent is searched through __proto__ until it is found. If the destination is found but not found, return NULL.
The chain formed by this search process is the prototype chain.
2.5 summary
(1) For objects:
Object with __proto__ and constructor properties, no prototype:
Object.__proto__ === parent constructor. Prototype
;Constructor === parent constructor. Prototype.constructor
. In general,Prototype. constructor === parent constructor
;
(2) For the function:
-
Prototype takes two arguments: constructor and __proto__ :
Constructor === parent constructor. Prototype.constructor
. In general,Prototype. constructor === parent constructor
;Constructor. Prototype. __proto__ === parent constructor
(e.g.,Date.prototype.__proto__ === Object.prototype
)
-
Functions are objects, so they also have __proto__ and constructor attributes, the same as (1);
-
Note: the constructor.prototype.__proto__ is different from the constructor.__proto__. Such as:
Date.prototype.__proto__ === Object.prototype; //true Date.prototype is an object; And the parent constructor of an Object is Object. Date.__proto__ === Function.prototype; // true // Since Date itself is a constructor, its parent constructor is Function. Copy the code
3) The top level of the scope chain is null.
3. Prototype chain diagram
Let’s look at a simple chestnut:
function Father() {};
const son = new Father();
Copy the code
Prototype, __proto__, constructor Let’s draw together
Step 1: Prototype
There is a constructor, Father, whose prototype is accessible through father.protorype.
Step 2: Instance instance
- The instance is
new
Out of theobject, so the instance owns__proto__
andconstructor
Two attributes; - Instance objectsThere is no
prototype
Attributes as well! (Instance method ==)
An instance object son is created using the new operator.
// Follow the chestnuts above
// The instance object has no Prototype property
son.prototype === undefined; // true
// Prototype (Father is an instance of Function)Father.prototype ! = =undefined; // true
Father.__proto__ === Function.prototype; // true
Copy the code
Step 3:__proto__
The instance’s __proto__ attribute points to the parent constructor’s prototype: father. prototype === son.__proto__
Step 4: Constructor
Step 5: Father’s members
The link between son, Father, Function and Object looks like this: (I suggest you look at the black line first, then look at the bright one)
self-test
Now that we have drawn the prototype chain diagram, the following judgments will be easy for you
// The object's __proto__ refers to the parent's prototype
son.__proto__ === Father.prototype; // true
// The constructor of an object points to its parent constructor
son.constructor === Father; // true
Constructor refers to the constructor itself, so the constructor of an instance object also refers to: constructor
son.constructor === Father.prototype.constructor; // true
// constructor refers to itself
Father.prototype.constructor === Father; // true
// Prototype is an Object whose parent is Object, so father.prototype.__proto__ refers to object.prototype
Father.prototype.__proto__ === Object.prototype; // true
// The parent of the constructor Father is Function, so Father.__proto__ refers to function. prototype
Father.__proto__ === Function.prototype; // true
// The constructor of a constructor is its parent function, so...
Father.constructor === Function; // true
/ / 1) constructor. The prototype. The constructor to the constructor itself, so the Function. The prototype. The constructor = = = Function; Function. Constructor == Function. Constructor == Function. 3) So they are equal
Father.constructor === Function.prototype.constructor; // true
// Function is itself an instance of its parent constructor. This is because: construction.prototype.constructor refers to the constructor itself
Function.prototype.constructor === Function; // true
// Function. Prototype is an Object, so...
Function.prototype.__proto__ === Object.prototype; // true
// Function is itself an instance of its parent constructor, but its parent constructor is still Function, so...
Function.__proto__ === Function.prototype; // true
// Function.__proto__ refers to Function
Function.__proto__.prototype === undefined; // true
// function.__proto__ ();
Function.__proto__.constructor === Function; // true
// Function.__proto__ is an instance of Function.
Function.__proto__.__proto__ === Object.prototype; // true
// Function.__proto__.__proto__.
Function.__proto__.__proto__.constructor === Object; //true
// function.__proto__.__proto__ refers to object. prototype
Function.__proto__.__proto__.__proto__ === null; //true
// Object is also a constructor. Prototype. constructor refers to the constructor itself
Object.prototype.constructor === Object; // true
// The level above object.prototype is the end of the prototype chain, which is null
Object.prototype.__proto__ === null; // true
// Object is also an instance of its parent constructor, so object.__proto__ refers to function.prototype
Object.__proto__ === Function.prototype; // true
// Object.__proto__ refers to its parent constructor
Object.__proto__.__proto__ === Object.prototype; // true
// Object.__proto__ refers to its parent constructor.
Object.__proto__.constructor === Function; // true
// 1) Object.__proto__ refers to the parent constructor. 2) Object. __proto__ refers to object. prototype; 3) object.prototype. __proto__ is null
Object.__proto__.__proto__.__proto__ === null; // true
Copy the code
4. Develop
4.1. Constructors
- A constructor looks like a normal function, but it creates objects with the new keyword;
- In general, public properties are defined in constructors, and public methods are placed on prototype objects (methods on the prototype are shared by the instance).
4.1.1. Instance and static members
- Instance members:
- Inside the constructor, the member added by this;
- It can only be accessed through an instantiated object.
- Static members:
- Members added to the constructor itself;
- It is accessible only through the constructor.
function Person(name, age) {
// Instance members
this.name = name;
this.age = age;
}
// Static members
Person.sex = 'woman';
const p1 = new Person('LaoHuang'.24);
console.log(p1.name); // 'LaoHuang'
console.log(p1.age); / / 24
console.log(p1.sex); // undefined (instance cannot access static members of constructor)
console.log(Person.name); // Person undefined (constructor cannot directly access instance member, must be instantiated to access)
console.log(Person.sex); // female (the constructor can access its static members)
Copy the code
4.1.2. New an instance
This process is called instantiation.
function Person(name) {
this.name = name;
}
const p1 = new Person('LaoHuang');
console.log(p1) // Person {name: "LaoHuang"}
Copy the code
P1 is an instance object. The process of creating a new object consists of the following steps:
- Create an empty object p1:
{}
; - Prepare the prototype chain link for P1:
p1.__protp__ = Person.prototype
; - Bind this to make the constructor’s this point to the new object p1:
Person.call(this)
; - Assign values to properties of the new object:
p1.name
; - Return to this:
return this
. The new object now has the methods and properties of the constructor.
4.1.3. Methods for sharing instances
Methods added to the constructor prototype are shared by the instance.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
console.log('Name:' + this.name);
}
const p1 = new Person('LaoHuang');
const p2 = new Person('FeiFei');
p1.getName(); // Name: LaoHuang
p2.getName(); // Name: FeiFei
console.log(p1.getName === p2.getName); // true
Copy the code
4.2 Class Class
-
The essence of a class is still a function, which is just another way of writing a constructor;
-
Classes have no variable promotion and must be defined before they can be instantiated.
-
The constructor method is the default method of the class and is automatically called when an object instance is generated with the new command. A class must have a constructor method. If not explicitly defined, an empty constructor method will be added by default.
-
All methods of a class are defined on its prototype:
class Person { constructor(name) { this.name = name; } getName() { console.log('Name:' + this.name); }}const p1 = new Person('LaoHuang'); const p2 = new Person('FeiFei'); p1.getName(); // Name: LaoHuang p2.getName(); // Name: FeiFei console.log(p1.getName === p2.getName); // true Copy the code
4.2.1. How do I add methods to a class
Use the Object. The assign ().
class Person {
constructor(name, sex) {
this.name = name;
this.sex = sex;
}
getName() {
console.log('Name:' + this.name); }}Object.assign(Person.prototype, {
getSex(){
console.log(this.name + The gender of 'is:' + this.sex)
}
});
const p1 = new Person('LaoHuang'.'woman');
const p2 = new Person('FeiFei'.'male');
p1.getSex(); // The gender of LaoHuang is female
p2.getSex(); // The gender of FeiFei is male
console.log(p1.getSex === p2.getSex); // true
Copy the code
4.3. Differences between classes and constructors
- Class must be called with new, otherwise an error will be reported. This is a major difference from normal constructors, which can be executed without new;
- All instances of a class share a prototype object;
- Class, the default is strict mode, so you do not need to use
use strict
Specify the running mode.
4.4. Inheritance
I’m not going to expand on inheritance here, just prototype-related. Try drawing a prototype
4.4.1. Constructors + prototype objects
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
console.log('Name:' + this.name);
};
function Girl(name, sex) {
When instantiated, this in Person points to the current instance
Person.call(this, name);
this.sex = sex;
}
// Girl.prototype = Person.prototype; // In this way, adding a prototype method to a subclass will also affect the superclass
Girl.prototype = new Person();
Girl.prototype.sing = function () {
console.log('I am singing');
};
let g1 = new Girl('little red'.'woman');
console.log(Person.prototype); // {getName: logon, constructor: logon}
console.log(Girl.prototype); // Person {name: undefined, sing: logon}
Copy the code
Its prototype chain diagram looks like this:
As you can see from this picture:
/ / 1) g1. Point constructor Girl. Prototype. The constructor
/ / 2) and Girl. The prototype is the Person instance, and the Girl. The prototype. The constructor is equivalent to (new Person) constructor, namely Person. The prototype. The constructor, The Person itself
g1.constructor === Person; //true
Copy the code
Consider this: what if you want g1.constructor === Girl?
4.4.2. Extends sugar
(1) Super:
Super can be used as a function and an object:
- When used as a function, it can only be used in the constructor of a subclass, representing the constructor of the superclass, but
super
In thethis
Refers to an instance of a subclass, so in a subclasssuper()
Represents theParent.prototype.constructor.call(this)
. - When used as an object,
super
Represents a superclass prototype object, i.eParent.prototype
.
(2) What extends does:
- Step 1: Inherit the prototype of the parent class, will subclass
__proto__
Pointing to the superclass itself; - The second step, call inheritance, is the processing of super(). Inherits object methods from the parent class to the child class object; This is why it is necessary to add super() to es6 inheritance, because you cannot inherit from the object properties of the parent class.
- Step 3: Create subclasses of their own methods.
class Person {
constructor(name){
this.name = name;
}
getName(){
return this.name; }}class Girl extends Person{
constructor(name, sex){
super(name);
this.sex = sex;
}
getSex(){
return this.getName() + 'gender:' + this.sex; }}const g1 = new Girl('little red'.'woman');
console.log(g1.getSex()); // Xiao Hong's gender: female
Copy the code
Its prototype chain diagram looks like this (remember to compare with the first inheritance) :
As you can see from this picture:
// This is where extends is special
Girl.__proto__ === Person; //true
Copy the code
Reference 5.
- 2020 Interview Harvest – JS prototype and prototype chain
- Diagram prototypes and prototype chains
- MDN – Object prototype