Создание экземпляра класса CoffeeScript по имени класса в строке - PullRequest
8 голосов
/ 18 января 2012

Как создать экземпляр класса в CoffeeScript, когда у меня есть только имя класса в строке?

class Dog
  bark:->
    "Woof"

className = "Dog"
dog = new className  # <--- I would like to create an instance here using the string

Ответы [ 4 ]

11 голосов
/ 18 января 2012

С некоторой предусмотрительностью вы можете сделать это довольно легко и защитите себя от использования eval. Сохраните где-нибудь список классов, которые вы хотите создать по имени:

class Dog
  bark:->
    "Woof"

# Or window.named_classes if you need to access
# `named_classes` globally (or just in another
# CoffeeScript file).
named_classes = { Dog: Dog }

и затем используйте таблицу поиска вместо eval:

name = 'Dog'
dog  = new named_classes[name]

Когда вы говорите class Dog, вы получаете локальную переменную с именем Dog:

var Dog;
Dog = (function() { /* ... */ })();

и нет никакого способа получить локальную переменную JavaScript, если вы не храните ее где-нибудь, к которому вы можете получить доступ по имени. Также обратите внимание, что eval не будет работать, если вы определите Dog в одном файле CoffeeScript и захотите получить к нему доступ в другом, CoffeeScript упаковывает каждый файл в самозапускающуюся анонимную функцию, чтобы ограничить область действия переменной :

все выходные данные CoffeeScript заключены в анонимную функцию: (function(){ ... })(); Эта защитная оболочка в сочетании с автоматической генерацией ключевого слова var чрезвычайно затрудняет случайное загрязнение глобального пространства имен.

Если вы хотите создать переменные верхнего уровня для использования другими сценариями, присоедините их в качестве свойств к окну или к экспорту объекта в CommonJS.

3 голосов
/ 20 января 2012

Если вы используете модули CommonJS, то можно ли что-то подобное сделать?

файл: Dog.coffee

class Dog
  sound: ()->
    "woof"

файл: Cat.coffee

class Cat
  sound: ()->
    "meow"

: Main.coffee

className = 'Dog'
Animal = require(className)
animal = new Animal
animal.sound
# => "woof"

className = 'Cat'
Animal = require(className)
animal = new Animal
animal.sound
# => "meow"
1 голос
/ 18 января 2012

Не берите в голову, что это не очень хороший код, но я не мог придумать лучшего способа.

Использование eval:

class Dog
  bark:->
    "Woof"


className = "Dog"
dog = new (eval(classname))()

Я продолжу думать.

0 голосов
/ 14 марта 2013

Как насчет этого?

dog.coffee

class Dog
  bark:->
    "Woof"

app.coffee

@Dog = require './dog'
className = "Dog"
dog = new @[className]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...