继承的7种方式

js的继承几种方式:

  1. es5的继承,原型链继承
    (子的prototype= new 父,子的prototype.constructor = 子)
function Parent(name){
  this.name = name
}
Parent.prototype.say = function(){
  console.log(this.name)
}
function Child(age){
  this.age = age
}
Child.prototype = new Parent('dhk')
Child.prototype.constructor = Child
var boy1 = new Child(39)
var boy2 = new Child(19)
缺点:1不能给父传值

          boy1.arr.push(2)
          boy2.arr  // [1,2]
           2引用类型的值是公共的。
  1. 构造函数继承(父在子的方法call(this,参数))
function Parent(name){
  this.name = name
  this.arr = [1]
  this.say = function(){
  console.log(this.name)
 }
}
function Child(name,age){
 Parent.call(this,name)
  this.age = age
}
var boy1 = new Child('dhk',39)
var boy2 = new Child('duan',19)
缺点:1.不能继承父的prototype对象上的属性方法
           2.重复实例父的this.方法

  1. 组合方法,把上面原型链方法和构造函数方法组合起来
    (父.call(this,参数) 子.prototype = new 父 子.prototype.constructor = 子)
function Parent(name){
  this.name = name
  this.arr = [1]
  this.say = function(){
  console.log(this.name)
 }
}
function Child(name,age){
 Parent.call(this,name)  // 第二次调用
  this.age = age
}
Child.prototype = new Parent('dhk') //第一次调用
Child.prototype.constructor = Child
var boy1 = new Child('dhk',39)
var boy2 = new Child('kun',19)
解决了上面的缺点,但是产生新的缺点
缺点:重复实例了父对象的属性,因为实例了2次
  1. 优化组合继承1
function Parent(name){
  this.name = name
  this.arr = [1]
  this.say = function(){
  console.log(this.name)
 }
}
function Child(name,age){
 Parent.call(this,name)  
  this.age = age
}
Child.prototype = Parent.prototype
Child.prototype.constructor = Child // 因为没有实例对象,这时parent和child的原型都指向child了
var boy1 = new Child('dhk',39)
var boy2 = new Child('kun',19)
解决了上面的缺点,但是产生新的缺点
缺点:因为没有实例对象,这时parent和child的原型都指向child了
  1. 优化组合继承2,又称寄生组合继承
    (Child.prototype = Object.create(Parent.prototype))

多继承:
other.call(child)
Object.assign(child.prototype, other.prototype)

function Parent(name){
  this.name = name
  this.arr = [1]
  this.say = function(){
  console.log(this.name)
 }
}
function Child(name,age){
 Parent.call(this,name)
  this.age = age
}
Child.prototype = Object.create(Parent.prototype) 
// 相当于Child.prototype.__proto__ = Parent.prototype
// 获取到原型,而且互相独立的
// 继承到Child.prototype的原型链上__proto__
Child.prototype.constructor = Child
var boy1 = new Child('dhk',39)
var boy2 = new Child('kun',19)
function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

// 继承一个类
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
     // do a thing
};
  1. 对象冒充法继承
function Parent(username){
  this.username = username;
  this.hello = function(){
   alert(this.username);
  }
}
function Child(username,password){
  //通过以下3行实现将Parent的属性和方法追加到Child中,从而实现继承
  //第一步:this.method是作为一个临时的属性,并且指向Parent所指向的对象,
  //第二步:执行this.method方法,即执行Parent所指向的对象函数
  //第三步:销毁this.method属性,即此时Child就已经拥有了Parent的所有属性和方法
  this.method = Parent;
  this.method(username);//最关键的一行
  delete this.method;
  this.password = password;
  this.world = function(){
   alert(this.password);
  }
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();

7.es6的最简单,关键字extends 、constructor、super()

// es6继承
  class Animal {
    //构造函数,里面写上对象的属性
    constructor(props) {
      this.name = props.name || 'Unknown';
    }
    //方法写在后面
    eat() {//父类共有的方法
      console.log(this.name + " will eat pests.");
    }
  }

  //class继承
  class Bird extends Animal {
    //构造函数
    constructor(props,myAttribute) {//props是继承过来的属性,myAttribute是自己的属性
      //调用实现父类的构造函数
      super(props)//相当于获得父类的this指向
      this.type = props.type || "Unknown";//父类的属性,也可写在父类中
      this.attr = myAttribute;//自己的私有属性
    }

    fly() {//自己私有的方法
      console.log(this.name + " are friendly to people.");
    }
    myattr() {//自己私有的方法
      console.log(this.type+'---'+this.attr);
    }
  }

//通过new实例化
  var myBird = new Bird({
    name: '小燕子',
    type: 'Egg animal'//卵生动物
  },'Bird class')
  myBird.eat()
  myBird.fly()
  myBird.myattr()

构造函数、原型、对象的三角关系
在这里插入图片描述

自己实现new,分三步:
//自己定义的new方法
let newMethod = function (Parent, …rest) {
// 1.以构造器的prototype属性为原型,创建新对象;
let child = Object.create(Parent.prototype);
// 2.将this和调用参数传给构造器执行
Parent.apply(child, rest);
// 3.返回第一步的对象
return child;
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值