方式一:通过原型链继承
缺点:
- 当父级构造函数接收参数时,无法给其传参
- 修改引用类型的属性时会影响其他实例
// 方式一:通过原型链继承
/**
* 缺点:1. 当父级构造函数接收参数时,无法给其传参 2. 修改引用类型的属性时会影响其他实例
*/
function Animal(type) {
this.type = type
this.age = 1
this.category = ['dog']
}
Animal.prototype.getAge = function() {
return this.age
}
function Cat(name) {
this.name = name
}
Cat.prototype = new Animal()
var cat = new Cat('mi')
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = new Cat('do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog', 'cat' ] 1
方式二:通过借用构造函数继承
优点:
- 可以传参
- 引用类型属性更改不会影响其他实例
缺点:无法继承原型链上的属性、方法
// 方式二:通过借用构造函数继承
/**
* 优点:1. 可以传参 2. 引用类型属性更改不会影响其他实例
* 缺点:1. 无法继承原型链上的属性、方法
*/
function Animal(type) {
this.type = type
this.age = 1
this.category = ['dog']
}
Animal.prototype.getAge = function() {
return this.age
}
function Cat(name, type) {
Animal.apply(this, type)
this.name = name
}
var cat = new Cat('mi')
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category) // mi [ 'dog', 'cat' ]
var cat1 = new Cat('do')
console.log(cat1.name, cat1.category) // do [ 'dog']
方式三:原型 + 构造函数 组合式继承
优点:结合了原型和构造函数的优点
缺点:调用了两次Animal
// 方式三:原型 + 构造函数 组合式继承
/**
* 优点:结合了原型和构造函数的优点
* 缺点:1. 调用了两次Animal
*/
function Animal(type) {
this.type = type
this.age = 1
this.category = ['dog']
}
Animal.prototype.getAge = function() {
return this.age
}
function Cat(name, type) {
Animal.apply(this, type)
this.name = name
}
Cat.prototype = new Animal()
var cat = new Cat('mi')
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = new Cat('do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog'] 1
方式四:原型继承
缺点:修改引用类型的属性时会影响其他实例
// 方式四:原型继承
/**
* 缺点:修改引用类型的属性时会影响其他实例
*/
var parentObj = {
age: 1,
category: ['dog'],
getAge: function() {
return this.age
}
}
function createObject(parent, name) {
const Fn = new Function()
Fn.prototype = parent
const obj = new Fn()
obj.name = name
return obj
}
var cat = createObject(parentObj, 'mi')
console.log(cat)
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = createObject(parentObj, 'do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog', 'cat'] 1
方式五:寄生式继承
创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象。
缺点:修改引用类型的属性时会影响其他实例
var parentObj = {
age: 1,
category: ['dog'],
getAge: function() {
return this.age
}
}
function createObject(parent, name) {
const obj = Object.create(parent)
obj.name = name
obj.sayName = function() {
return obj.name
}
return obj
}
var cat = createObject(parentObj, 'mi')
console.log(cat)
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = createObject(parentObj, 'do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog', 'cat'] 1
方式六:寄生组合式继承
优点:结合了原型和构造函数的优点,完美解决了原型和构造函数的缺点
// 方式六:寄生组合式继承
/**
* 优点:结合了原型和构造函数的优点,完美解决了原型和构造函数的缺点
*/
function Animal(type) {
this.type = type
this.age = 1
this.category = ['dog']
}
Animal.prototype.getAge = function() {
return this.age
}
function Cat(name, type) {
Animal.apply(this, type)
this.name = name
}
Cat.prototype = Object.create(Animal.prototype)
Cat.prototype.constructor = Cat
var cat = new Cat('mi')
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = new Cat('do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog'] 1
方式七:es6里的class继承
class Animal {
constructor(type) {
this.type = type
this.age = 1
this.category = ['dog']
}
getAge() {
return this.age
}
}
class Cat extends Animal{
constructor(name, type) {
super(type)
this.name = name
}
}
var cat = new Cat('mi')
cat.category.push('cat')
cat.age = 2
console.log(cat.name, cat.category, cat.getAge()) // mi [ 'dog', 'cat' ] 2
var cat1 = new Cat('do')
console.log(cat1.name, cat1.category, cat1.getAge()) // do [ 'dog'] 1