js继承

Posted by Eric on November 23, 2018

使用对象冒充实现继承(该种实现方式可以实现多继承)

实现原理:让父类的构造函数成为子类的方法,然后调用该子类的方法,通过this关键字给所有的属性和方法赋值

function Parent(firstname)
{
    this.fname=firstname;
    this.age=40;
    this.sayAge=function()
    {
        console.log(this.age);
    }
}
function Child(firstname)
{
    this.parent=Parent;
    this.parent(firstname);
    delete this.parent;
    this.saySomeThing=function()
    {
        console.log(this.fname);
        this.sayAge();
    }
}
var mychild=new  Child("李");
mychild.saySomeThing();

采用call方法改变函数上下文实现继承(该种方式不能继承原型链,若想继承原型链,则采用5混合模式)

实现原理:改变函数内部的函数上下文this,使它指向传入函数的具体对象

function Parent(firstname)
{
    this.fname=firstname;
    this.age=40;
    this.sayAge=function()
    {
        console.log(this.age);
    }
}
function Child(firstname)
{

    this.saySomeThing=function()
    {
        console.log(this.fname);
        this.sayAge();
    }
   this.getName=function()
   {
       return firstname;
   }

}
var child=new Child("张");
Parent.call(child,child.getName());
child.saySomeThing();

采用Apply方法改变函数上下文实现继承(该种方式不能继承原型链,若想继承原型链,则采用5混合模式)

实现原理:改变函数内部的函数上下文this,使它指向传入函数的具体对象

function Parent(firstname)
{
    this.fname=firstname;
    this.age=40;
    this.sayAge=function()
    {
        console.log(this.age);
    }
}
function Child(firstname)
{

    this.saySomeThing=function()
    {
        console.log(this.fname);
        this.sayAge();
    }
    this.getName=function()
    {
        return firstname;
    }

}
var child=new Child("张");
Parent.apply(child,[child.getName()]);
child.saySomeThing();

采用原型链的方式实现继承

实现原理:使子类原型对象指向父类的实例以实现继承,即重写类的原型,弊端是不能直接实现多继承

function Parent()
{

    this.sayAge=function()
    {
        console.log(this.age);
    }
}
function Child(firstname)
{
    this.fname=firstname;
    this.age=40;
    this.saySomeThing=function()
    {
        console.log(this.fname);
        this.sayAge();
    }
}

Child.prototype=new  Parent();
var child=new Child("张");
child.saySomeThing();

采用混合模式实现继承

缺点:调用了两次父类构造函数,生成了两份实例

function Parent()
{

    this.sayAge=function()
    {
        console.log(this.age);
    }
}

Parent.prototype.sayParent=function()
{
   alert("this is parentmethod!!!");
}

function Child(firstname)
{
    Parent.call(this);
    this.fname=firstname;
    this.age=40;
    this.saySomeThing=function()
    {
        console.log(this.fname);
        this.sayAge();
    }
}

Child.prototype=new  Parent();
Child.prototype.constructor = Parent;
var child=new Child("张");
child.saySomeThing();
child.sayParent();

寄生组合继承

通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){
  // 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //将实例作为子类的原型
  Cat.prototype = new Super();
})();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true