1. 原型链
1.1. 核心概念
- _ proto_(隐式原型)
每个对象都有一个__proto__属性,该属性指向创建该对象的构造函数的prototype属性
- prototype(显示原型)
只有函数才有,是函数用来给实例对象继承的原型
- 原型链
对象通过__proto__属性一层层向上查找原型,形成的链式结构
1.2. 原型链作用
实现继承
子类可以使用父类上原型上的属性和方法
节省内存
所有实例共享原型上的属性和方法,不用每个对象都创建一份
2. new关键字的执行流程
step1- 创建空对象
step2- 新对象的__proto__指向构造函数的prototype
step3- 构造函数内部this绑定为新对象,执行构造函数
step4- 返回实例
// 自己手搓的代码
const newFn = (Fn: any, ...args: any[])=>{
const obj = {}
obj.__proto__ = Fn.prototype
const result = Fn.apply(obj, args)
return result !== null && typeof result === 'object' ? result : obj
}
const newUser = newFn(function A (name,age){
this.name = name
this.age = age
}, '张三', 18)
console.log(newUser)
//AI给优化后的,增加了注释的内容都是自己查了资料的,需要多留意
//<T>():T的ts写法是定义函数的返回值为T的语法格式
const newFn = <T>(Fn:(...args:any[])=>any,...args:any[]):T=>{
//as T 告诉编译器:obj的类型是 T,把可能的宽泛的类型缩窄精确到T
const obj = Object.create(Fn.prototype) as T
const result = Object.apply(obj,args)
// 如果传入的Fn 有返回值,则用result返回结果,
// 如果没有返回值则是undefined使用obj作为返回值
return result!==null && typeof result == 'object'? result : obj
}
//this是给编译器看的,而不是实际要传的参数
const User = (this:{name:string,age:string},name:string,age:string)=>{
this.name = name
this.age = age
}
//这里的newFn 后面的尖括号内容是 告诉T泛型的真实参数类型
const newUser =newFn<{name:string,age:string}>(User,'张三',‘18’)
3. ES5 寄生组合继承
寄生:通过一个中间函数prototype来继承原型
组合:结合借用构造函数和原型链继承
function inheritPrototype(child,parent){
const prototype = Object.create(parent.prototype)
prototype.constructor = child
child.prototype = prototype
}
function Parent(name){
this.name = name
}
Parent.prototype.sayName = function(){
console.log(this.name)
}
function Child(name,age){
Parent.call(this,name)
this.age = age
}
inheritPrototype(Child,Parent)
Child.prototype.sayAge = function(){
console.log(this.age)
}
const child1 = new Child('张三',18)
const child2 = new Child('李四',20)
child1.sayName()
child1.sayAge()
child2.sayName()
child2.sayAge()
4. ES6 Class继承
核心语法:extends与super
class Animal{
constructor(name){
this.name = name
}
speak(){
console.log(`${this.name}speak`)
}
static create(){
}
}
class Dog extends Animal{
constructor(name,breed){
super(name) //先用super才能使用this
this.breed = breed
}
speak(){
super.speak();
console.log(`{this.name} barks!`)
}
}
const dog = new Dog('Buddy', 'Golden');
dog.speak();