我想改进一个小框架,因此我想摆脱对eval
的两次调用。
让代码说话:
# irf.coffee (The Framework)
# Classes which are appended to the namespace 'IRF'
classes = [
"Background"
"BoundingBox"
# ...
]
# Namespace where to attach classes
@IRF = {}
# TODO: Get rid of eval(c)
for c in classes
@IRF[c] = eval(c)
我只希望IRF
'污染'全局命名空间,以便我可以访问像new IRF.Background()
这样的类/对象。
此框架的目标是由包括此框架在内的其他项目使用。 所以我可能有这样一个项目:
class TowerMap extends IRF.Game
constructor: (width, height) ->
@background = new IRF.Background(width, height)
如你所见,我必须在这里使用IRF
命名空间,但在这个特定的项目中,我想在没有命名空间的情况下使用它,就像我这样做:
# Require all Class of IRF, so we won't need namespace here
# TODO: get rid of eval
eval("var #{k} = v") for k,v of IRF
class TowerMap extends Game
constructor: (width, height) ->
@background = new Background(width, height)
一切都按预期工作,但不知何故,这两个eval
打扰了我。
可能有另一种解决方案吗?
答案 0 :(得分:1)
为什么不直接导入你需要的位?
Background = IRF.Background
class TowerMap extends Game
constructor: (width, height) ->
@background = new Background(width, height)
您应该知道,EcmaScript 5严格模式中的eval
无法引入新的变量声明,因此在严格模式下eval('var x = ...')
不会生成对周围非eval代码可见的变量。< / p>
严格模式
eval
代码无法将调用者的变量环境中的变量或函数实例化为eval
。而是创建一个新的变量环境,该环境用于eval
代码的声明绑定实例化(10.4.2)。
答案 1 :(得分:1)
无法从当前上下文中按名称访问本地变量(至少在ecmascript中。也许coffeescript有一些非标准的扩展名。)
只能访问某个对象的属性。也可以访问全局变量,因为它们是全局对象的属性;这是浏览器中的window
,可以在ecma-3中获得(function(){ return this })()
。