Что такое элегантный синтаксис смешивания / композиции для классов ES6? - PullRequest
0 голосов
/ 10 мая 2019

Я ищу чистый и простой способ смешивать методы с различными классами. Большинство примеров, которые мне удалось найти, используют прототип JS , например this

Пример кода:

const _ = require("underscore")

let actions = {
  speak() {
    console.log(this.name + " animal speak")
  },

  look() {
    console.log(this.name + " animal looks")
  }
}

class Dog {
  constructor(name) {
    console.log("new Dog", name)
    this.name = name

    // modify instance and return
    let that = _.extend(this, actions)
    return that
  }

  speak() {
    console.log(this.name + " dog speaks")
  }

  bark() {
    console.log(this.name + " dog barks")
  }

}

function test() {
  let rover = new Dog("rover")

  // speak in "actions" overrides Dog.speak method
  rover.speak() // => rover animal speak

  // runtime works but ts-lint doesn't like it
  // look property doesn't exist on type 'dog'
  rover.look() // => rover animal looks

  // from dog since the method doesn't exist on actions
  rover.bark() // => rover dog barks
}

test()

Таким образом, чтобы использовать прототип, я мог бы изменить вышеприведенное как:

Object.assign(Dog.prototype, actions)

, а затем просто используйте ванильный конструктор, который возвращает this

class Dog {

  constructor(name) {
    this.name = name
  }
...
}

Object.assign(Dog.prototype, actions)

В обоих случаях метод mixin speak заменит метод Dog Class speak, ок.

Итак, мой вопрос: есть ли какой-нибудь другой более простой / понятный метод для смешивания методов в разных классах?

А что-то не так с добавлением к прототипу? Это создание копий реальных методов? Если это только в прототипе, а не в каждом экземпляре, я думаю, что все в порядке, но не совсем ясно, какие там последствия для памяти.

1 Ответ

0 голосов
/ 10 мая 2019

В качестве альтернативы использованию миксинов вы можете использовать наследование с помощью extends для переопределения методов в классе.

Недостатком наследования по сравнению с миксинами является то, что вы можете расширять только один класс за раз, но выМожно использовать несколько миксинов.Так что это зависит от того, какой вариант использования вы используете.

Вот пример:

class Animal {
  constructor(name) {
    console.log("new", this.constructor.name, name)
    this.name = name

  }
  
  speak() {
    console.log(this.name + " animal speak")
  }

  look() {
    console.log(this.name + " animal looks")
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name)
  }

  speak() {
    console.log(this.name + " dog speaks")
  }

  bark() {
    console.log(this.name + " dog barks")
  }

}

const dog = new Dog('Fred')
// Will call the overridden speak method on Dog
dog.speak() // Fred dog speaks
// Will call look on Animal as it hasn't been overriden in Dog
dog.look() // Fred animal looks
...