Open Jack-rainbow opened 5 years ago
function myClass(obj) {
const constructor = obj.constructor
let extendParent = null
function MyClass() {
if (constructor) {
const mySuper = (...args) => {
if (extendParent) {
const parent = args.length ? eval(`new extendParent(${args.map(i => typeof i === 'string' ? `"${i}"` : String(i)).join(',')})`) : new extendParent()
Object.assign(this, parent)
}
}
let tempObj
eval(`tempObj = {${constructor.toString()}}`)
tempObj.constructor.apply(this, arguments)
}
}
const pro = Object.assign({}, obj, { constructor: MyClass })
MyClass.prototype = pro
MyClass.extends = function (parent){
extendParent = parent
Object.setPrototypeOf(pro, new parent())
MyClass.extends = null
return MyClass
}
return MyClass
}
const Person = myClass({
constructor(name, age) {
this.name = name
this.age = age
},
introduce() {
console.log(`Hello!My name is ${this.name}.I'm ${this.age} years old.`)
}
})
const person = new Person('Jack', 23)
person.introduce() // Hello!My name is Jack.I'm 23 years old.
const Cook = myClass({
constructor(name, age) {
mySuper(name, age)
this.profession = 'cook'
},
introduce() {
console.log(`Hello!My name is ${this.name}.I'm ${this.age} years old.I'm a ${this.profession}.`)
}
}).extends(Person)
const cook = new Cook('Tom', 22)
cook.introduce() // Hello!My name is Tom.I'm 22 years old.I'm a cook.
const cook2 = new Cook('Jerry', 18)
cook2.introduce() // Hello!My name is Jerry.I'm 18 years old.I'm a cook.
const Special = myClass({
constructor(name, age) {
mySuper(name, age)
this.profession = 'special cook'
},
}).extends(Cook)
const special = new Special('George', 28)
special.introduce() // Hello!My name is George.I'm 28 years old.I'm a special cook.
实现 ES6 的 class 语法