This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
1 introduction
Proto__ __proto__ constructor (); proto__ constructor (); proto__ constructor (); This is how to place the object you want to inherit on the prototype chain of the object you want to inherit.
2. Prototype chain inheritance
Prototype = Function ()
const Animal = function () {}
Animal.prototype.eat = function () {
console.log('i eat')}const Dog = function () {}
// Dog.prototype = new Animal()
// Object.setPrototypeOf(Dog.prototype, new Animal())
Dog.prototype = Object.create(new Animal())
Dog.prototype.constructor = Dog // Better fix it
const dog = new Dog()
dog.eat()
Copy the code
Dog. Prototype (new Animal(), new Animal(eat), new Animal(eat)) Find eat on its prototype object animal. prototype
Other six inheritance modes
- Borrow constructor inheritance
- Combination of inheritance
- Primary inheritance
- Parasitic inheritance
- Parasitic combinatorial inheritance
- Mixin inherits multiple objects
It’s all rubbish, it’s all rubbish, it’s just I don’t want to remember…
4 class inheritance
The main thing to learn is class inheritance, which is also implemented through Prototype inheritance and is a syntax candy.
If possible, I would prefer not to modify prototype properties directly in the code, such as prototype.xxx = XXX. This code is really hard to read, and the implementation of inheritance code should be done first.
/ / parent class
class Animal {
constructor(options) {
typeof options === 'object' && Object.assign(this, options)
}
say() {
console.log('i ... ')}}// Subclass inherits parent class
class Dog extends Animal {
constructor(options) {
// In the constructor of a subclass, we need super() before we can use this, so we can call the constructor of the parent class to get the instance properties of the parent class
super(options)
this.options = options
}
eat() {
console.log('i eat')}}Copy the code
TSC converts TS to JS after simplifying the code result
/** * inherit method *@param {*} The child subclass *@param {*} The parent class b * /
var __extends = function (child, parent) {
if (typeofb ! = ='function'&& parent ! = =null)
throw new TypeError(
'Class extends value ' + String(parent) + ' is not a constructor or null'
)
// Copy static methods from the parent class to the child class, because properties that cannot be read from child class will be read from parent class
Object.setPrototypeOf(child, parent)
if (parent === null) {
// If the parent class is null, the stereotype is set to null
child.prototype = Object.create(parent)
} else {
// If the parent class is a function,
// Use prototype chain inheritance directly
child.prototype = new parent()
child.prototype.constructor = child
}
}
// Why is it an immediate function, because class does not promote, it can be done this way.
// But const cannot be simulated
var Animal = / * *@class * / (function () {
// Class is actually a function,
// constructor is the function ontology
function Animal(options) {
typeof options === 'object' && Object.assign(this, options)
}
// The method is implemented through prototypes
Animal.prototype.say = function () {
console.log('i ... ')}return Animal
})()
var Dog = / * *@class * / (function (_super) {
// Inherits the parent class
__extends(Dog, _super)
function Dog(options) {
// Instantiate the parent class to get the instance attributes of the parent class
var _this = _super.call(this, options) || this
_this.options = options
return _this
}
Dog.prototype.eat = function () {
console.log('i eat')}return Dog
})(Animal)
Copy the code
5 diy inheritance
A purely diy
const protoArr = Symbol('protoArr')
const addProto = (child, parent) = > {
if(! child[protoArr]) {// I can't change the pointing of child.prototype, so I can change the pointing of child.prototype
const originProto = Object.getPrototypeOf(child.prototype)
// Save its original prototype object and the prototype object to be added
child[protoArr] = new Set([originProto, parent.prototype])
const newProp = new Proxy({}, {get(target, key) {
// Retrieve attributes from each of the saved prototype objects
const value = [...child[protoArr]].find((i) = >i? .[key] ! = =void 0)? .[ key ]return value
},
}
)
// If the property is not read on child.prototype, go back to its prototype and read it. Then the proxy object is read and can be intercepted
Object.setPrototypeOf(child.prototype, newProp)
} else {
// Add the desired prototype chain directly to the save location
child[protoArr].add(parent.prototype)
}
}
const delProto = (child, parent) = > {
if(! child[protoArr]) {// There is no new prototype object
return
} else {
// Delete it
child[protoArr].delete(parent.prototype)
}
}
class Style1 {
width() {
return 100}}class Style2 {
height() {
return 100}}class Style3 {
color() {
return '#ccc'}}class Style4 {}
Style4.prototype.fontSize = '12px'
class Style5 {
backgroundColor() {
return 'red'}}const getStyle = (style) = > {
const keys = ['width'.'height'.'color'.'fontSize'.'backgroundColor']
return keys.reduce((total, cur) = > {
if (style[cur]) {
total[cur] = typeof style[cur] === 'function' ? style[cur]() : style[cur]
}
return total
}, {})
}
class Style {}
const style = new Style()
console.log(getStyle(style))
// {} At this point, it and its prototype chain cannot read any properties
addProto(Style, Style1)
addProto(Style, Style2)
addProto(Style, Style3)
addProto(Style, Style4)
addProto(Style, Style5)
console.log(getStyle(style))
/ / {
// width: 100,
// height: 100,
// color: '#ccc',
// fontSize: '12px',
// backgroundColor: 'red',
// }
delProto(Style, Style2)
console.log(getStyle(style))
/ / {
// width: 100,
// color: '#ccc',
// fontSize: '12px',
// backgroundColor: 'red',
// }
Copy the code
6 summarizes
Inheritance is achieved by modifying the prototype object.
7 finally
Inheritance remember so much, if there is some enlightenment for you, welcome to like, comment, pay attention to, collect…
As usual, I enclose a few previous posts
- Vue2 source code analysis nextTick
- Code snippet JS flow limiting scheduler
- Linked Lists of Data Structures and Algorithms (1)
- Vue2 source code parsing event system $on
- Vue2 – Global API source code analysis
- Vue-class-component (1)
Js native syntax prototype,__proto__ and constructor