Javascript 调用;新";在Coffeescript中以编程方式
可能重复:Javascript 调用;新";在Coffeescript中以编程方式,javascript,coffeescript,Javascript,Coffeescript,可能重复: 我希望能够以编程方式调用new。例如,如果我有这两个类: class Bird constructor: (@name) -> class Snake constructor: (@name) -> 我可以调用s=newsnake(“Sam”)。现在,我想做的是 bird_class = "Bird" b = new bird_class() 并且能够从字符串构造一个bird对象。这在CoffeeScript或Javascript中可能吗?我不是一个C
我希望能够以编程方式调用
new
。例如,如果我有这两个类:
class Bird
constructor: (@name) ->
class Snake
constructor: (@name) ->
我可以调用s=newsnake(“Sam”)
。现在,我想做的是
bird_class = "Bird"
b = new bird_class()
并且能够从字符串构造一个bird对象。这在CoffeeScript或Javascript中可能吗?我不是一个Coffeescripter,但在Javascript中,您可以做到:
function MyClass() { ... constructor ... };
function MyOtherClass() { ... other constructor ... };
var theConstructor = something ? MyClass : MyOtherClass;
var obj = theConstructor();
您只需获取对构造函数的引用,并将其视为一个值,随意处理即可
如果你想点名,那就有点棘手了。除了使用
eval()
(如果您愿意,也可以这样做,如果您可以确定这样做对您的项目没有风险的话),在JavaScript中不可能获得这样的符号引用。但是,如果它是对对象属性的引用,则它确实有效。如果将类保留在对象中,则始终可以:
var animals = {
Snake: Snake,
Bird: Bird
};
new animals["Snake"]();
根据您的评论,这样的模式可以让您注册类
在飞行中。这是生的,但可能会给你一个想法:
var zoo = {
animals: {},
add: function (animal) {
this.animals[animal.name] = animal;
},
make: function(name) {
if (this.animals[name]) {
return new this.animals[name]();
}
}
};
function Snake() {};
zoo.add(Snake);
var snake = zoo.make('Snake');
如果您在回答上述链接问题时确实使用了这种方法,请意识到您将需要导出类,例如,
window.Bird=Bird
@icktoofay谢谢您的提醒。有没有一种方法可以在不导出类的情况下执行此操作?使用上述方法,将发生以下情况:包含一个脚本。脚本使用窗口添加引用。Bird=Bird
。然后我用coffeescript调用新窗口['Bird']
?这是可行的,但如果有其他方法的话会很有趣。是的,但是如果没有eval
(这可能是危险的,并且会阻碍可能的优化),您就必须将它们都放在一个对象中。@icktoofay有没有办法扩展varbird\u类
来获取值,这样我就可以调用eval了?问题是我只有变量bird\u class
可以工作with@Scoop:是的,但我会这样做:bird\u class=eval bird\u class\u name;my_bird=new bird_class(arg1,arg2)
或在一条语句中,new(eval bird_class_name)(arg1,arg2)
。当然,可以省略参数,但更令人惊讶的是,如果没有参数,可以省略参数括号。(你不能省略(eval bird\u class\u name)
周围的括号)我需要能够做到这一点,而不必事先知道类的列表。你在某处定义了它们,对吗?定义过程的一部分可能是将它们注册到动物
,或任何有趣的地方。我明白你的意思。将zoo
做得更好,然后将每个类追加到窗口中
?在大多数情况下,您都希望避免向窗口中添加大量变量。通常情况下,最好将内容封装在对象或模块中。首先,这样就不会与窗口名称空间中的其他代码发生冲突。另外,使用这样的工厂型解决方案,您将能够更好地对所有类进行封装。e、 g.您想查看定义的动物类的数量吗?:zoo.animals.length
哈哈,对不起,我猜应该是Object.keys(zoo.animals.length
。。。被我自己的打字错误愚弄了(我把动物当作一个数组)除了eval()
,还可以使用窗口(或者这个对窗口的引用
):b=新窗口[bird_class]()
,尽管它与eval()
有同样的问题(虽然稍微安全一些).如何使用eval
?有没有办法将varbird\u类
扩展到var的值,这样我就可以调用eval了?@Scoop:eval('a')
将获得名为a
的变量的值,但是,如果用户输入,这有点危险,因为它还可以计算其他表达式。@Scoop:这也使得不可能安全地缩小代码变得非常困难,因为缩小器不会知道您传递给eval
的所有可能的内容。