如何在不使用eval的情况下在Coffeescript中动态创建命名类?

如何在不使用eval的情况下在Coffeescript中动态创建命名类?,coffeescript,Coffeescript,我想能够写: 生成“猫”、“喵喵” 并定义generate函数,使其产生: class Cat meow: -> @.__proto__.constructor.name + ' says meow.' 这样我就可以写: garfield = new Cat garfield.meow() # "Cat says meow" 如果“命名类”指的是“具有命名函数的类”,那么在CoffeeScript或JavaScript中您所要求的是不可能的。没有eval,就无法创建与函数F

我想能够写:

生成“猫”、“喵喵”

并定义
generate
函数,使其产生:

class Cat
  meow: ->
    @.__proto__.constructor.name + ' says meow.'
这样我就可以写:

garfield = new Cat
garfield.meow() # "Cat says meow"
如果“命名类”指的是“具有命名函数的类”,那么在CoffeeScript或JavaScript中您所要求的是不可能的。没有
eval
,就无法创建与
函数FuncName(){…}
等价的函数。您只能在使用该语法定义的函数上使用
\uuu proto\uu.constructor.name
属性

语法是在CoffeeScript中创建命名函数的唯一方法,原因如中所述。

如果“命名类”是指“具有命名函数的类”,那么在CoffeeScript或JavaScript中您所要求的是不可能的。没有
eval
,就无法创建与
函数FuncName(){…}
等价的函数。您只能在使用该语法定义的函数上使用
\uuu proto\uu.constructor.name
属性


语法是在CoffeeScript中创建命名函数的唯一方法,原因请参见。

如果您不介意污染您的全局命名空间,我实际上在“try CoffeeScript”运行程序中运行了以下代码段:

不是100%符合你的要求,但几乎符合你的要求,不是吗

编辑:实际上,第一个脚本只在浏览器中工作,而不是基于(
Node.js
的)CLI,更正了该脚本

如果你知道你将只在浏览器中生活,你可以松开
root.Cat
,只说
Cat
,但是如果你想要Node.js和浏览器兼容,你必须与
root.

编辑2:通常最好从生成函数返回类,而不是神奇地将其放入命名空间中。也可以使方法名成为动态的。从@Loren,提问者那里获得了一些灵感(注意,它不再需要引用全局对象):


如果您不介意污染您的全局命名空间,我实际上在“try coffeescript”运行程序中运行了以下代码段:

不是100%符合你的要求,但几乎符合你的要求,不是吗

编辑:实际上,第一个脚本只在浏览器中工作,而不是基于(
Node.js
的)CLI,更正了该脚本

如果你知道你将只在浏览器中生活,你可以松开
root.Cat
,只说
Cat
,但是如果你想要Node.js和浏览器兼容,你必须与
root.

编辑2:通常最好从生成函数返回类,而不是神奇地将其放入命名空间中。也可以使方法名成为动态的。从@Loren,提问者那里获得了一些灵感(注意,它不再需要引用全局对象):


我被你的例子弄糊涂了。您想
生成“猫”、“喵”来生成既不包含
“猫”
也不包含
“喵”
的代码吗?对不起,我已经更正了示例。我被您的示例弄糊涂了。您想
生成“猫”,“喵”来生成既不包含
“猫”
也不包含
“喵”
的代码吗?很抱歉,我已经更正了示例。最新版本(Cat=gen…)现在不在coffeescript测试页面中运行。我得到了“UncaughtTypeError:非法调用”。有什么想法吗?最新版本(Cat=gen…)现在不在coffeescript测试页面中运行。我收到了“未捕获的类型错误:非法调用”有什么想法吗?
root = exports ? window
alert = alert or console.log

gen = (clsname, val) ->
  root[clsname] = class
    meow: => "#{clsname} says #{val}"

gen 'Cat', 'meow'
g = new root.Cat
alert g.meow()

gen 'Dog', 'woff'
d = new root.Dog
alert d.meow()
alert = alert or console.log

gen = (clsname, val) ->
  C = class
  C.prototype[val] = -> "#{clsname} says #{val}"
  C

Cat = gen 'Cat', 'meow'
console.log Cat
g = new Cat
alert g.meow()

Dog = gen 'Dog', 'woff'
d = new Dog
alert d.woff()