我们对于知识的理解尊崇 案例从简 的方式,无需讲解很多种,提取几个经典实现即可。
构造函数
// 声明一个构造函数
function Person (name) {
this.name = name || 'Person'
this.sleep = function () {
console.log(`${this.name}--正在睡觉`)
}
}
// 原型上添加<eat>方法
Person.prototype.eat = function (food) {
console.log(`${this.name}--在吃--${food}`)
}
let p01 = new Person()
// 打印属性和方法
console.log(p01.name) // Person
p01.sleep() // Person--正在睡觉
p01.eat('食物') // Person--在吃--食物
继承
-
- 原型链继承
特点
:基于原型链,既是父类的实例,也是子类的实例缺点
:无法实现多继承
function ZhangSan () {}
ZhangSan.prototype = new Person('张三')
let zs01 = new ZhangSan()
// 打印属性和方法
console.log(zs01.name) // 张三
zs01.sleep() // 张三--正在睡觉
zs01.eat('饼干') // 张三--在吃--饼干
-
- 构造函数继承
特点
:可以实现多继承缺点
:只能继承父类实例的属性和方法,不能继承原型上的属性和方法
function LiSi (name) {
Person.call(this)
this.name = name || 'LiSi'
}
let ls01 = new LiSi('李四')
// 打印属性和方法
console.log(ls01.name) // 李四
ls01.sleep() // 李四--正在睡觉
ls01.eat('面包') // Error: ls01.eat is not a function
-
- 组合继承
特点
:可以继承实例属性/方法,也可以继承原型属性/方法缺点
:调用了两次父类构造函数,生成了两份实例
function WangWu (name) {
Person.call(this)
this.name = name || 'WangWu'
}
WangWu.prototype = new Person()
let ww01 = new WangWu('王五')
// 打印属性和方法
console.log(ww01.name) // 王五
ww01.sleep() // 王五--正在睡觉
ww01.eat('米饭') // 王五--在吃--米饭
-
- 寄生组合继承
特点
:可以继承实例属性/方法,也可以继承原型属性/方法@des
: 通过寄生方式,砍掉父类的实例属性;这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性@tip
: 【 最佳方案 】
function ZhaoLiu (name) {
Person.call(this)
this.name = name || 'ZhaoLiu'
}
(function () {
// 创建一个没有实例方法的类
let Super = function () {}
Super.prototype = Person.prototype
ZhaoLiu.prototype = new Super()
})()
let zl01 = new ZhaoLiu('赵六')
// 打印属性和方法
console.log(zl01.name) // 赵六
zl01.sleep() // 赵六--正在睡觉
zl01.eat('汉堡') // 赵六--在吃--汉堡