提示:主要是原型链继承、构造函数继承、原型链加构造函数继承、寄生组合式继承
一、原型链继承
子类想要继承父类的属性和方法,可以将其原型对象指向父类的实例,根据原型链就可以使用到父类的方法和属性
// 父类
function Parent() {
this.name = ['父类']
this.introduce = function () {
console.log("my name is" + this.name)
}
}
// 子类
function Child() {
this.childname = ['子类']
}
// 核心代码:
Child.prototype = new Parent()
var child1 = new Child()
console.log(child1)
输出的结果:
child已经继承了父类的方法,但是缺点就是多个子类实例对父类引用类型的操作会被纂改,无法保持子类实例的个性。如:
var child1 = new Child()
child1.name[0] = 'child1唱歌'
var child2 = new Child()
child2.name[0] = 'child2跳舞'
console.log(child1.name);
console.log(child2.name);
输出结果:
child1和child2继承的父类的name属性是一个数组,对其操作时更改会互相影响。
二、构造函数继承
在子类的构造函数中,执行父类的构造函数,并且为其绑定子类的this
// 父类
function Parent() {
this.name = ['父类']
this.introduce = function () {
console.log("父类上的introduce方法")
}
}
Parent.prototype.sayhi = function () {
console.log('父类原型上的sayhi方法');
}
// 子类
function Child() {
this.childname = ['子类']
Parent.call(this)
}
var child1 = new Child()
child1.introduce()
child1.sayhi()
上述代码的结果是:
构造函数继承可以继承到父类上的属性和方法,但是继承不到父类原型上的属性和方法
三、原型链加构造函数继承
// 父类
function Parent() {
this.name = ['父类']
this.introduce = function () {
console.log("父类上的introduce方法")
}
}
Parent.prototype.sayhi = function () {
console.log('父类原型上的sayhi方法');
}
// 子类
function Child() {
this.childname = ['子类']
Parent.call(this) // 第二次调用Parent
}
Child.prototype = new Parent() // 第一次调用Parent
var child1 = new Child()
console.log(child1);
输出结果:
第一次调用Parent(),在Child.prototype写入了父类的name和introduce属性和方法,第二次再调用Parent(), 给实例child1又写入了name和introduce属性和方法。实例child1上的name和introduce屏蔽了原型对象Parent.prototype的两个同名属性,所以组合模式的缺点就在使用子类创建实例对象的时候,其原型中会存在两份相同的属性和方法.
四、原型式继承
利用一个空对象作为中介、将某个对象直接赋值给空对象构造函数的原型,其实就是使用Object.create()
var Parent = {
name: ['父类属性'],
sayhi: function () {
console.log(this.name);
}
}
var child1 = Object.create(Parent)
var child2 = Object.create(Parent)
child1.name[0] = 'child1属性'
child2.name[0] = 'child2属性'
console.log(child1);
缺点:跟原型链继承一样,多个子类实例的引用类型属性指向相同,可能会纂改。
五、寄生组合式继承
// 父类
function Parent() {
this.name = ['父类']
this.introduce = function () {
console.log("父类上的introduce方法")
}
}
Parent.prototype.sayhi = function () {
console.log('父类原型上的sayhi方法');
}
// 子类
function Child() {
this.childname = ['子类']
Parent.call(this) // 核心代码
}
Child.prototype = Object.create(Parent.prototype) // 核心代码
const child1 = new Child()
const child2 = new Child()
child1.name[0] = 'child1'
child2.name[0] = 'child2'
console.log(child1);
console.log(child1.name);
console.log(child2.name);
完美解决原型链加构造函数继承的缺点
mark一下,明天接着写