簡體   English   中英

CoffeeScript中的動態類生成

[英]Dynamic class generation in CoffeeScript

在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! 和獅子說咆哮! 但它看起來有點復雜。 我想知道是否有更簡單的方法來實現這個結果,可能是直接訪問原型。 還是我完全走錯了路?

由於sound是Animal實例的默認值,因此您可以將其設置為類定義的屬性:

class Cat extends Animal
    sound: 'meow!'

garfield = new Cat "garfield"
garfield.speak() # "garfield says meow!"

然后

for animal in animalDefinitions
    animal.class = class extends Animal
        sound: animal.sound

mutant = new animalDefinitions[0].class "mutant"
mutant.speak() # "mutant says eek!"

如果你想要sound可以覆蓋,你可以做到

class Animal
    constructor: (@name, sound) ->
        @sound = sound if sound? 
    speak: ->
        console.log "#{@name} says #{@sound}"

對於你的直接問題(循環中的閉包不捕獲當前值,但是最新的閉包),有do構造:

for animal in animalDefinitions
  do (animal) ->
    animal.class = class extends Animal
      constructor: (@name) ->
        @sound = animal.sound

不知何故,我預計的CoffeeScript自動照顧這一點,因為這是在JavaScript中一個常見的錯誤,但至少有do有把它寫一個簡潔的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM