Каков наилучший способ динамически создавать классы в CoffeeScript, чтобы впоследствии создавать экземпляры их объектов?
Я нашел способы сделать это, но я не уверен, может быть, есть даже лучший (или более простой) способ добиться этого. Пожалуйста, дайте мне знать ваши мысли о моем коде.
Давайте начнем с простых нединамических классов:
class Animal
constructor: (@name) ->
speak: ->
alert "#{@name} says #{@sound}"
class Cat extends Animal
constructor: (@name) ->
@sound = "meow!"
garfield = new Cat "garfield"
garfield.speak()
Как и ожидалось, Гарфилд говорит мяу!
Но теперь мы хотим динамически генерировать классы для большего количества животных, которые определены следующим образом:
animalDefinitions = [
kind: 'Mouse'
sound: 'eek!'
,
kind: 'Lion'
sound: 'roar!'
]
Первая наивная попытка не удалась:
for animal in animalDefinitions
animal.class = class extends Animal
constructor: (@name) ->
@sound = animal.sound
mutant = new animalDefinitions[0].class "mutant"
mutant.speak()
Животное, которое мы только что создали, mutant
, должно быть мышью. Тем не менее, это говорит рев! Это потому, что animal.sound оценивается только тогда, когда мы создаем экземпляр класса. К счастью, из JavaScript мы знаем проверенный способ решить эту проблему: закрытие:
for animal in animalDefinitions
makeClass = (sound) ->
class extends Animal
constructor: (@name) ->
@sound = sound
animal.class = makeClass(animal.sound)
mickey = new animalDefinitions[0].class "mickey"
mickey.speak()
simba = new animalDefinitions[1].class "simba"
simba.speak()
Теперь все работает по желанию, говорит Микки Маус. и симба лев говорит рев! Но это уже выглядит несколько сложно. Мне интересно, есть ли более простой способ достичь этого результата, возможно, путем прямого доступа к прототипу. Или я совершенно не на том пути?