1、原型链继承
/*
1、原型链继承
优点:可以继承父类中的所有方法
缺点:父类中所有引用类型会被子类共享
子类实例不能给父类构造函数传参
*/
function Person(){
this.name = '张三',
this.eats = ['米饭']
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法')
}
function Student() {}
Student.prototype = new Person()
const stu1 = new Student()
stu1.name = '李四'
stu1.eats.push('大白菜')
console.log(stu1.name)
console.log(stu1.eats)
stu1.getName()
stu1.get()
console.log('------------------')
const stu2 = new Student()
stu2.name = '王五'
console.log(stu2.name)
console.log(stu2.eats)
stu2.getName()
stu2.get()
输出:
李四
[ '米饭', '大白菜' ]
李四
Person.prototype上的方法
------------------
王五
[ '米饭', '大白菜' ]
王五
2、构造函数继承
/*
2、构造函数的继承
优点:父类的引用类型的数据不会被子类共享,不会相互影响
缺点:子类不能访问父类原型属性上的属性和方法
*/
function Person(){
this.name = '张三',
this.eats = ['米饭']
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法')
}
function Student() {
Person.call(this)
}
const stu1 = new Student()
stu1.name = '李四'
stu1.eats.push('大白菜')
console.log(stu1.name)
console.log(stu1.eats)
stu1.getName()
// stu1.get()
console.log('------------------')
const stu2 = new Student()
stu2.name = '王五'
console.log(stu2.name)
console.log(stu2.eats)
stu2.getName()
// stu2.get()
输出:
李四
[ '米饭', '大白菜' ]
李四
------------------
王五
[ '米饭' ]
王五
3、组合继承
/*
3、组合继承
优点:父类可以复用
父类构造函数中的引用数据不会被共享
缺点:会调用两次父类构造函数,会有两份一样的属性和方法,影响性能
*/
function Person(){
this.name = '张三',
this.eats = ['米饭']
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法')
}
function Student() {
Person.call(this)
}
Student.prototype = new Person()
const stu1 = new Student()
stu1.name = '李四'
stu1.eats.push('大白菜')
console.log(stu1.name)
console.log(stu1.eats)
stu1.getName()
stu1.get()
console.log('------------------')
const stu2 = new Student()
stu2.name = '王五'
console.log(stu2.name)
console.log(stu2.eats)
stu2.getName()
stu2.get()
输出:
李四
[ '米饭', '大白菜' ]
李四
Person.prototype上的方法
------------------
王五
[ '米饭' ]
王五
Person.prototype上的方法
4、寄生组合继承
/*
4、寄生组合继承
*/
function Person(){
this.name = '张三',
this.eats = ['米饭']
this.getName = function() {
console.log(this.name)
}
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法')
}
function Student() {
Person.call(this)
}
const Fn = function () {}
Fn.prototype = Person.prototype
Student.prototype = new Fn()
const stu1 = new Student()
stu1.name = '李四'
stu1.eats.push('大白菜')
console.log(stu1.name)
console.log(stu1.eats)
stu1.getName()
stu1.get()
console.log('------------------')
const stu2 = new Student()
stu2.name = '王五'
console.log(stu2.name)
console.log(stu2.eats)
stu2.getName()
stu2.get()
输出:
李四
[ '米饭', '大白菜' ]
李四
Person.prototype上的方法
------------------
王五
[ '米饭' ]
王五
Person.prototype上的方法
5、es6中的class类继承
/*
5、es6中的class类继承
*/
class Person {
constructor () {
this.name = '张三',
this.eats = ['米饭']
this.getName = function() {
console.log(this.name)
}
}
get = () => {
console.log('Person.prototype上的方法')
}
}
class Student extends Person {}
const stu1 = new Student()
stu1.name = '李四'
stu1.eats.push('大白菜')
console.log(stu1.name)
console.log(stu1.eats)
stu1.getName()
stu1.get()
console.log('------------------')
const stu2 = new Student()
stu2.name = '王五'
console.log(stu2.name)
console.log(stu2.eats)
stu2.getName()
stu2.get()
输出:
李四
[ '米饭', '大白菜' ]
李四
Person.prototype上的方法
------------------
王五
[ '米饭' ]
王五
Person.prototype上的方法