【发布时间】:2011-11-23 08:02:55
【问题描述】:
在 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()
现在它可以正常工作了,米老鼠说 eek!狮子辛巴吼叫着!但它看起来已经有些复杂了。我想知道是否有更简单的方法来实现这个结果,也许是直接访问原型。还是我完全走错了路?
【问题讨论】:
-
你真的需要不同的课程吗?似乎它们只是在某些属性的值上有所不同,那么只有一个类
Animal和一些实例呢? -
我也问过自己是否需要不同的课程。看来我有。我需要的不仅仅是 Animal 的实例。我需要大象的实例,斑马的实例等。所有斑马共享某些属性,所有大象共享其他属性。它们都具有一些基本的动物特性。而且我在设计时不知道这些事情,因为上帝的创造是在一个配置文件中(只能在运行时读取)。我发现只有一个类没有令人满意的方法来模拟这个。 (当然,真正的应用是不同的):)
标签: javascript oop closures coffeescript