【JS】继承

153 阅读3分钟

基于原型的继承

创建一个构造函数的全过程(记得还有notability笔记:构造函数new)

//定义构造函数时,给参数写自身属性
let Dog = new Function('name','return this.name=name')
 //我们要用“爸爸构造函数”window.Function写一个构造函数Dog(),我们需要写入一个参数name,之后会把这个name赋值给this的name属性(this用来以后会被指为我们将要创建的新对象。),写在这里面的属性都算是自身属性。
 
 //该构造函数的原型上写共有属性
Dog.prototype.wangwang = function(){console.log('狗在汪汪叫')}//因为Dog是个函数所以是个对象,所以有prototype属性。现在往prototype属性里面新加一个属性wangwang,这个wangwang属性的值是一个可以打印出“狗在汪汪叫”的函数。写在这里的属性都将是以后创建对象的共有属性。
Dog.prototype.run = function(){console.log('狗在跑')}//同上

//用构造函数构造一个新对象
let dog1 = new Dog('小兵')
function Parent(name1){
  this.name1 = name1
}
Parent.prototype.pMethod = function(){
  console.log(this.name1)
}

function Child(name2, name1){
    Parent.call(this, name1) // 执行Parent函数(注意不是new Parent函数),把this也就是将要创建的child对象当成Parent函数的this,这样自身属性就继承来了
    this.name2 = name2
}
Child.prototype.__proto__ = Parent.prototype //child对象的共有属性的原型是Parent函数的prototype,这样就在child对象的共有属性里又把Parent对象的共有属性继承过来了
//上面这句代码的古板写法应该是下面三句
//const empty = function(){}
//empty.prototype = Parent.prototype
//Child.prototype = new empty()
//古板写法额外加两分

Child.prototype.cMethod = function(){
    console.log(this.name2)
}

//如果写成下面这种,就扣两分
//Child.prototype = {
//    cMethod: function(){
//        console.log(this.name2)
//    }
//}

基于class的继承

class Dog{
    constructor(name){  //constructor里给参数,写自身属性
        this.name=name
    }
    wangwang(){console.log('狗在汪汪叫')}  //外面写共有属性
    run(){console.log('狗在跑')}
}

//用构造函数构造一个新对象
let dog1 = new Dog('小兵')

new Dog

当我们使用new Dog('小兵')是,其实干了四件事

①自动创建一个空对象

②自动将该空对象的原型指向 X.prototype(即将 X.prototype 保存的地址复制到空对象.__proto__里)这时空对象就有了共有属性

③自动将空对象作为this关键字运行构造函数。这时空对象就有了自身属性

④自动return this,返回我们创建好了的对象。命名为dog1。

同样的原型写三遍,就应该用继承:如EventBus

//在EventBus.js中
import $ from 'jquery'

class EventBus {
  constructor() {
    this._eventBus = $(window)
  }

  on(eventName, fn) {
    return this._eventBus.on(eventName, fn)
  }

  trigger(eventName, data) {
    return this._eventBus.trigger(eventName, data)
  }

  off(eventName, fn) {
    return this._eventBus.off(eventName, fn)
  }
}

export default EventBus

//在Model.js中
import EventBus from './EventBus'

class Model extends EventBus {   //让Model类继承EventBus类的所有属性
  constructor(options) { 
    super()                      //特别的。要这样把EventBus的constructor弄过来
    const keys = ['data', 'update', 'create', 'delete', 'get']
    keys.forEach((key) => {
      if (key in options) {
        this[key] = options[key]
      }
    })
  }

  create() {
    console && console.error && console.error('你还没有实现 create')
  }

  delete() {
    console && console.error && console.error('你还没有实现 delete')
  }

  update() {
    console && console.error && console.error('你还没有实现 update')
  }

  get() {
    console && console.error && console.error('你还没有实现 get')
  }
}


export default Model
class Parent{
    constructor(name1){
        this.name1 = name1
    }
    pMethod(){
        console.log(this.name1)
    }
}
class Child extends Parent{
    constructor(name2, name1){
        super(name1) // 得分点
        this.name2 = name2
    }
    cMethod(){
        console.log(this.name2)
    }
}