The original address
It’s just notes. Corrections are welcome
Prototype chain
1. Overall combing
-
__proto__ is instance specific and normally points to the prototype of its constructor
-
Prototype is unique to functions. Function declarations come with prototype objects
-
Constructor is unique to the Prototype object and points to the constructor
-
Functions are instances of Function and objects, so functions have both __proto__ and constructor
-
In ES6 __proto__ can be operated with object. getPrototypeOf and Object.getPrototypeOf
Second, the Function
Function = Function
typeof Function.prototype // "function"
Function.prototype instanceof Function // false
Function.prototype instanceof Object // true
Copy the code
-
Prototype types are functions that are compatible with previous versions of EcmaScript
-
Prototype is itself an Object, an instance of Object, but internally implements the [[Call]] property to be executable, returning undefined
Third, the Object
- An Object is a Function and therefore an instance of Function
Object.__proto__ === Function.prototype // true
Copy the code
-
Object. Prototype is an Object, but its __proto__ is null.
-
A normal Function is an instance of Function whose prototype is an instance of Object
function Foo() {}
Foo.__proto__ === Function.prototype // true
Foo.prototype.__proto__ === Object.prototype // true
Copy the code
inheritance
Implementation of Class inheritance
You have two chains of inheritance
- Prototype refers to the prototype parent class and is used to inherit properties and methods from the prototype
class Parent {}
class Child extends Parent {}
Child.prototype.__proto__ === Parent.prototype // true
Copy the code
- Subclass stereotypes point to the parent class and are used to inherit static properties and methods
Child.__proto__ === Parent // true
Copy the code
- When implemented internally, the parent class is called in the subclass constructor to inherit instance properties and methods
function Child() {
Parent.call(this)}Copy the code
Second, the Babel polyfill
You can compile it on Babel’s website
class Parent {
constructor() {
this.setup()
}
static level = 'parent'
setup = () = > {
console.log("parent")}}class Child extends Parent {
id = 61
setup = () = > {
console.log("child")}getId() {
console.log("child getId")
return id
}
}
new Child()
Copy the code
-
Function property setup (or function expression) is treated as a normal property and implemented via defineProperty
-
The function declaration getId hangs on Prototype
-
In addition, attribute assignment is done in the constructor, and function declaration is separated from the constructor by “inheritance closure” and attached to Prototype
-
The previous point has implications for JS inheritance. As you can see from print, setup ends up executing functions on parent because Child already has function attributes attached to parent. Call (this)
-
Although it is convenient to bind this to function attributes when writing them, extra care needs to be taken when inheriting
Third, instanceof
- Polyfill: By iterating
__proto__
And compare it to the prototype of the object until null is reached, the end of the prototype chain
function instanceOf(object, target) {
while(object ! =null) {
if (object == target.prototype) return true
object = object.__proto__
}
return false
}
instanceOf(new Date(), Object) // true
Copy the code
- Find the details
function A() {}
function B() {}
/ / 1
A.prototype = B.prototype
/ / 2
A.prototype = new B()
/ / 3
A.prototype = Object.create(B.prototype)
const a = new A()
Copy the code
-
2 and 3 are inherited “semi-finished products”, only inheriting the attributes and methods on prototype B. Operation of A.prototype will not affect B.prototype
-
1 is assignment. A and B share the same prototype object, and operating on one affects the other. But with instanceof
B.prototype.constructor === B // true
a instanceof A // true
a instanceof B // true
Copy the code
-
Constructor does not affect the judgment of instanceof
-
Prototype. constructor was originally a legacy of JS design and wasn’t formally defined and used until ES6. In keeping with good practice, try to have your prototype’s constructor point to its constructor