0
点赞
收藏
分享

微信扫一扫

javascript中的继承

javascript中的几种继承方式

原型链继承

es6中提出了原型链的概念,原型链也成为js中实现继承的一种主要手段,其实现原理主要实现方式如一下代码所示:

Object.prototype.age = '20'
function Gradefather () {
  this.property = true
}
Gradefather.prototype.get = function () {
  console.log('曾祖父的get方法')
}
function Father () {
  this.fatherproperty = false
  this.name = '刘备'
}
Father.prototype = new Gradefather()
const son = new Father()
Father.prototype.set = function () {
  console.log('父亲的set方法')
}
const son = new Father()
son.name = '阿斗'
son.get() // 曾祖父的get方法
son.set() // 父亲的set方法
console.log(son.property) // true
console.log(son.fatherproperty) // false
console.log(son.name) // 阿斗
console.log(son.age) // 20
console.log(son.job) // undefind

上面简单的示例展示了原型链的继承过程,son作为Father的实例,继承了Father构造函数中的属性fatherproperty 和set方法,而Father构造函数的原型又是Gradefather构造函数的实例,这样son作为Father的实例同时继承了Father和Gradefather的属性和方法;这样我们形象的描绘出通过原型链继承的过程:在访问实例son中的属性或者方法的时候,首先会在实例内部查找如**'name’属性**,如果在实例中查找不到将会网上一层的原型对象中查找如set方法和fatherproperty属性,如果在上一层还没找到的话就会继续往上一层查找如property属性和get方法, 以此层层递进形成一条链,而这条链的尽头就是Object对象,Object中的属性会被所有下次的实例继承如age属性,如果Object中都没有找到的属性则会返回undefined如:job

断开原型链

function Father () {
   this.job = '皇帝'
}
function Son () {
}
Son.prototype = new Father()
Son.prototype = {
  get: function () {
     return this.job
  }
}
const son = new Son()
console.log(son.get()) // undefined

上面代码中我们在第一次将Father的实例赋值给Son原型对象之后由使用对象字面量的方式重写了Son的原型对象,当使用Son的原型对象中的get方法访问job的时候发现返回的是unidefind,这就说明原型链被截断了,对象字面量赋值原型对象的方式我们还是需要谨慎使用;

借用构造函数组合式继承

原型链的概念让我们能够在js中使用继承这一特性实现很多事情,但是原型链的继承方式也是有一定的弊端的。比如说,我现在想让一个数组通过继承的方式传递给每个实例,我们知道,原型对象最大的优点就是共享属性和方法给每个实例,但是遇到引用类型的时候就会暴露一些问题,如下代码:

function P1 () {
   this.arr = ['1','2','3']
}
function P2 () {
}
P2.prototype = new P1()
const o1 = new P2()
const o2 = new P2()
o1.arr.push('7')
console.log(o1.arr) // ['1','2','3','7']
console.log(o2.arr) // ['1','2','3','7']

所以这个时候我们就需要借助构造函数的特性与原型进行组合继承,将上面的代码进行改造看下结果:

function P1 (name) {
   this.arr = ['1','2','3']
   this.name = name
}
function P2 (name) {
   P1.call(this, name)
}
P2.prototype = new P1()
const o1 = new P2('刘备')
const o2 = new P2('关羽')
o1.arr.push('7')
console.log(o1.arr) // ['1','2','3','7']
console.log(o2.arr) // ['1','2','3']
console.log(o1.name, o2.name) // 刘备  关羽

代码中可以看出,P2构造函数使用call方法继承了P1函数,这样在每次new P2()的时候就会将P1中的代码执行一遍,使每个P2的实例都继承了不同的属性,这样就解决了引用类型的问题;同时还可以进行传参来初始化实例的属性。

举报

相关推荐

0 条评论