es5继承与es6继承

可紊 提交于 2020-02-03 03:54:15

es5中的继承方式:

1. 原型链继承

       缺点:1. 创建实例时无法像父类构造函数传递参数;

                  2. 因为指定了原型,所以不能实现多继承;

                  3. 父类构造函数上的属性被所有子类共用,给原型上的属性赋值会改变其他子类的属性值;

// es5
const Parent = function (name, age) {
  this.name = name
  this.age = age
}

Parent.prototype.sayName = function () {
  console.log('My name is ' + this.name)
}

function Child (sex) {
  this.sex = sex
}

/* 
  Child.prototype = new Parent()
  let p1 = new Child('Json')
  p1.sayName() // console.log('my name is ', p1.name)

  let p2 = new Child('Ketty')
  p2.sayName()

  // My name is undefined
  // My name is undefined
*/

/** 
  Child.prototype = new Parent('Cole')
  let p1 = new Child('Json')
  p1.sayName()

  let p2 = new Child('Ketty')
  p2.sayName()
  // My name is Cole
  // My name is Cole
*/

Child.prototype = new Parent()
let p1 = new Child()
p1.__proto__.name = "Json"
p1.sayName()

let p2 = new Child()
p2.sayName()
// My name is Json
// My name is Json

p2.name = 'AA'
p1.sayName()
p2.sayName()
// My name is Json
// My name is AA

2. 构造函数继承

可以多继承,只要执行多个call方法即可;创建实例时能像父类构造函数传递参数;不会出现父类属性,所有子类构造函数共享

缺点: 不能继承父类原型链上的方法(如sayName方法),所以要继承的函数只能定义在父类的构造函数上,不能到达函数复用;子类构造函数的实例,原型链上并不存在父类构建函数

function Parent(name) {
  this.name = name
}

Parent.prototype.sayName = function () {
  console.log('my name is ', this.name)
}

let a = new Parent('Json')
a.sayName()

function Child (name, sex) {
  this.sex = sex
  Parent.call(this, name)
}

let p = new Child('Yarn', 8)
console.log('my name is ', p.name)
p.sayName()  // 报错

3.组合继承,融合以上两种方式

function Parent(name) {
  this.name = name
}

Parent.prototype.sayName = function () {
  console.log('my name is ', this.name)
}

function Child (name, sex) {
  this.sex = sex
  Parent.call(this, name)
}

Child.prototype = new Parent()
// Child.prototype = Object.create(Parent.prototype)  //寄生组合继承
Child.prototype.constructor = Child

let p = new Child('Yarn', 8)
console.log('my name is ', p.name)
p.sayName()

es6中的继承

es6中使用extend实现继承

class person {
  constructor (name,age) {
      this.name = name
      this.age = age
  }
  sayName () {
      console.log('my name is ', this.name)
  }
}

class child extends person {
  constructor (name,age,sex) {
    //  执行父类的构造函数,子类必须在构造函数中掉用super
    super(name,age)
    //  使用this一定要在super 之后 
    this.sex = sex
  }
}

let p = new child('czklove','23','man')
console.log(p)

 

prototype与__proto__

1. 对象有__proto__属性, 函数有prototype属性;

2. 对象由函数生成;

3. 生成对象时,对象的__proto__属性指向函数的prototype属性

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!