在Javascript中对变量进行惰性求值

时间:2016-07-28 23:31:34

标签: javascript eval lazy-evaluation

我有一个配置:

hierarchy = {
    // all different Geos
    State: {
        'dataSource'  : $scope.stateData,
        'class'       : 'stateContainer',
        'fillColor'   : 'red',
        'stroke-width': 2
    },
    County: {
        'dataSource'  : $scope.countyData,
        'class'       : 'countyContainer',
        'fillColor'   : 'green',
        'stroke-width': 1
    }
    // same for zip3, zip5 etc...
    // config options list shortened for simplicity
};

然后,有一个绘图函数,一个函数,它取我想要绘制的名称(State或County或...),如下面的伪代码所示:

function drawGeo(geoName) {
    /* pseudocode */

    // this is OK
    something.attr('class', hierarchy.geoName.class)

    // not OK
    var data = loadData(hierarchy.geoName.dataSource) 
}

使用这种配置的原因是为了避免使用单独的函数来绘制每个地理位置(状态...),并将所有绘图配置集中在一个地方(而不是在代码和每个函数周围管理函数参数)呼叫)。

鉴于hierarchy.geoName.class是一个字符串,它在设置时没有问题。其他常量如stroke-width

也是如此

但是,dataSource会导致问题,主要是因为在构造层次结构配置期间未定义$scope.stateData$scope.countyData

我一直在寻找一些方法来制作这些变量" lazy",并且只在访问它们时才能获取它们(可以在Scala和其他语言中完成)。

一个明显的策略是将dataSource中的变量括在引号之间(因此它们变成了字符串)。然后,使用eval:

获取绘图函数中变量的实际内容
'dataSource'  : '$scope.stateData',
...

loadData(eval(hierarchy.geoName.dataSource))  // works

这可能会吸引 eval()=邪恶军队。所以问题是:

  1. 鉴于$ scope.geoData的内容受到控制,eval的安全问题应该不用担心,对吧?在这种情况下,以这种方式使用eval()应该是安全的吗?

  2. 是否还有其他javascript方法可以将懒惰的提取变量视为较少" evil"?

  3. 如果" eval"在这种情况下,还有其他任何建议吗?

  4. 谢谢!

1 个答案:

答案 0 :(得分:1)

在评论中关注@ Bergi的建议:

  eval在这里是邪恶的(主要是因为它很慢,很难调试,而且   错误的工具)

     

相反,请将其返回到以下函数中:

'dataSource': function() { return $scope.stateData }
     

然后,用:

调用它
loadData(hierarchy.geoName.dataSource())