js如何实现一个继承?手写一个js继承

在js中,继承就是让一个对象拥有另一个对象的属性和方法。

(Father代表父类构造函数,Son代表子类构造函数,默认构造函数的方法都是写在原型中,实例化对象共享原型中的方法,避免了内存空间的浪费)

 

1. 原型链继承 (有两种实现方式) 

//1.
Son.prototype = Father.prototype
/**
 * 弊端:Son.prototype.constructor 指向Father,需要手动更改为Son ;Son的实例化对象只能继承Father原型中的方法,无法继承Father本身的属性。
 */

//2.
Son.prototype = new Father()
/**
 * 弊端:Son.prototype.constructor 指向Father,需要手动更改为Son;Son的实例化对象共享Father自身的引用类型属性。
 */

// 举个例子
function Father () { 
  this.name = "smd"; 
  this.arr = [1, 2, 3] 
}

function Son () { }

Son.prototype = new Father()

var s1 = new Son(), s2 = new Son();

s1.arr.push(4);

console.log(s1.arr) //--------> [1,2,3,4]

console.log(s2.arr) //--------->[1,2,3,4]
// Son的实例化对象s1,s2继承了Father的属性arr,但是s1,s2是同时指向这一属性的。

2.借助构造函数继承

function Father () {
  this.name = "smd";
  this.age = 26
};

function Son () {
  Father.call(this)
  // Father.apply(this) 
}

// 弊端:Son只能继承Father自身的属性,而无法继承Father原型中的方法。

3.组合式继承

function Father () {
  this.name = "smd";
  this.age = 26
}

Father.prototype.sayHi = function () {
  alert("hello")
}
function Son () {
  Father.call(this)
}

Son.prototype = new Father()

var s = new Son();
// 弊端:通过Father.call() 和 new Father() ,父类构造函数Father被调用了两次。

4.原型继承

function createObj (o) {
  function F () { }
  F.prototype = o;
  return new F()
}

var obj = { name: "smd", age: 26, sayHi: function () { } }

var newObj = createObj(obj);
// newObj继承了obj的属性和方法,但是同样出现了共享父类中引用类型属性的问题

5.经典继承

function create (obj) {
  if (Object.create) {
    return Object.create(obj)
  } else {
    function F () { } F.prototype = o; return new F()
  }
}

// 存在兼容问题,需要做浏览器的能力检查

6.寄生式继承

function createObj (o) {
  function F () { }
  F.prototype = o;
  return new F()
}

function createObj2 (o) {
  var obj = createObj(o);
  obj.sayHi = function () { }
  return obj
}

var obj = { name: "smd", age: 26, sayHi: function () { } }

var newObj = createObj2(obj)

// newObj继承了obj的属性和方法,但是同样出现了共享父类中引用类型属性的问题。

7.寄生组合式继承

function inheritPrototype (Child, Father) {
  var prototype = object(Father.prototype);//创建对象
  prototype.constructor = Child;//增强对象
  Child.prototype = prototype;//指定对象 }
  function Father (name) {
    this.name = name;
    this.arr = [1, 2, 3, 4];
  }
  Father.prototype.sayName = function () {
    console.log("父类原型" + this.name);
  }
  function Child (name, age) {
    Father.call(this, name);
    this.age = age;
  }
  inheritPrototype(Child, Father)
  Child.prototype.sayAge = function () {
    console.log(this.age);
  }

  var child1 = new Child(), child2 = new Child();

  child1.arr.push(5) // [1,2,3,4,5]


  child2.arr // [1,2,3,4].

  // 优点:可以多重继承 解决两次调用 解决实例共享引用类型的问题 原型链保持不变
}

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宋哈哈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值