文字列内のクラスの名前のみを持つ場合、CoffeeScriptでクラスをインスタンス化するにはどうすればよいですか?文字列内のクラス名からCoffeeScriptクラスをインスタンス化する
class Dog
bark:->
"Woof"
className = "Dog"
dog = new className # <--- I would like to create an instance here using the string
文字列内のクラスの名前のみを持つ場合、CoffeeScriptでクラスをインスタンス化するにはどうすればよいですか?文字列内のクラス名からCoffeeScriptクラスをインスタンス化する
class Dog
bark:->
"Woof"
className = "Dog"
dog = new className # <--- I would like to create an instance here using the string
先見の明が少しありますが、とは、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変数で取得する方法はありませんsomewherあなたは名前でアクセスできます。また、あなたは1つのCoffeeScriptファイルでDog
を定義し、それを別のものをアクセスする場合eval
は、CoffeeScript wraps each file in self-executing anonymous function to limit variable scopeに動作しませんのでご注意:
すべてのCoffeeScriptの出力は匿名関数でラップさ:
(function(){ ... })()
。この安全ラッパーは、キーワードvar
の自動生成と組み合わされているため、偶然にグローバルな名前空間を汚染することは非常に困難です。あなたはウィンドウ上、またはCommonJSで輸出オブジェクトのプロパティとしてそれらを添付し、使用する他のスクリプトのトップレベルの変数を作成したい場合。
これは非常に良いコードではありませんが、私はより良い方法を考えることができませんでした。 eval
を使用して
:
class Dog
bark:->
"Woof"
className = "Dog"
dog = new (eval(classname))()
私は考えておこう。
ええ、私はこのことについて考えたが、私は、より魅力的な方法があるだろう期待していました。 –
非常に不必要なevalへの呼び出しがダウンしました。評価を避ける! ミューはここで正しい答えを持っています。 –
@ChrisSubagio私はそれが良い考えではないと言った、私はちょうどより良いものと考えることができませんでした。 – Jivings
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"
これはどう?
dog.coffee
class Dog
bark:->
"Woof"
app.coffee
@Dog = require './dog'
className = "Dog"
dog = new @[className]
これは同等です: クラス@Dog 樹皮: - > "横糸" クラス名= '犬 犬=新しいこの[クラス名] 警告dog.bark() –
これを追加するには、事実の後でそれらを収集するのではなく、それらがネームスペースで始まる方が便利かもしれません。 どこかの前に他のすべて: 'MyClassesを指し= {}'後で : 'クラスmyClasses.Dog' 最後に:'犬=新しいMyClassesを指します[ "犬"] ' –
@クリス:はい、それは良い点です。あなたは 'class window.Dog'または' class window.named_classes.Dog'を使うことができますが、 'window.Dog'は' window'と 'window.named_classes.Dog'を汚染する危険性があり、' Dog'へのローカルアクセスは面倒です。あなたは 'named_classes.Dog = class Dog ...'を実行することもできますが、それはIMOです、少し醜いです。 –
@Chris:私たちは同時にコメントを編集しているようです(私のインターネット接続は面倒です!)。とにかく、目的の効果を得るにはさまざまな方法がありますが、重要なのは、オブジェクトにどこかのオブジェクトへの参照を格納して、プログラムにアクセス可能な名前を付けることです。 –