Javascript 中变量的惰性求值
lazy evaluation of variables in Javascript
我有这样的配置:
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
};
然后是绘图函数,一个函数取我想要绘制的名称(州或县或...),如下面的伪代码所示:
function drawGeo(geoName) {
/* pseudocode */
// this is OK
something.attr('class', hierarchy.geoName.class)
// not OK
var data = loadData(hierarchy.geoName.dataSource)
}
使用这种配置的原因是为了避免使用单独的函数来绘制每个地理区域(State ...),并将所有绘图配置集中在一个地方(而不是在代码周围管理函数参数和每个函数调用)。
由于hierarchy.geoName.class
是一个字符串,所以设置时不会有问题。其他常量也是如此,例如 stroke-width
.
但是,dataSource 导致问题,主要是因为 $scope.stateData
和 $scope.countyData
在构建层次配置时未定义。
我正在寻找一些方法来制作这些变量 "lazy",并且只在访问它们时获取它们(可以在 Scala 和其他语言中完成)。
一个明显的策略是将 dataSource 中的变量括在引号之间(这样它们就变成了字符串)。然后,使用 eval:
获取 draw 函数中变量的实际内容
'dataSource' : '$scope.stateData',
...
loadData(eval(hierarchy.geoName.dataSource)) // works
这可能会吸引 eval() = evil 军队。所以问题是:
鉴于 $scope.geoData 的内容是受控的,eval 的安全问题应该不用担心,对吧?在这种情况下,以这种方式使用 eval() 应该是安全的?
是否还有其他 javascript 延迟获取变量的方法被认为较少 "evil"?
如果 "eval" 在这种情况下不好,还有其他建议吗?
谢谢!
在评论中遵循@Bergi 的建议:
eval is evil here (mostly because it's slow, hard to debug, and the
wrong tool)
Instead, return it in a function such as:
'dataSource': function() { return $scope.stateData }
Then, call it with:
loadData(hierarchy.geoName.dataSource())
我有这样的配置:
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
};
然后是绘图函数,一个函数取我想要绘制的名称(州或县或...),如下面的伪代码所示:
function drawGeo(geoName) {
/* pseudocode */
// this is OK
something.attr('class', hierarchy.geoName.class)
// not OK
var data = loadData(hierarchy.geoName.dataSource)
}
使用这种配置的原因是为了避免使用单独的函数来绘制每个地理区域(State ...),并将所有绘图配置集中在一个地方(而不是在代码周围管理函数参数和每个函数调用)。
由于hierarchy.geoName.class
是一个字符串,所以设置时不会有问题。其他常量也是如此,例如 stroke-width
.
但是,dataSource 导致问题,主要是因为 $scope.stateData
和 $scope.countyData
在构建层次配置时未定义。
我正在寻找一些方法来制作这些变量 "lazy",并且只在访问它们时获取它们(可以在 Scala 和其他语言中完成)。
一个明显的策略是将 dataSource 中的变量括在引号之间(这样它们就变成了字符串)。然后,使用 eval:
获取 draw 函数中变量的实际内容'dataSource' : '$scope.stateData',
...
loadData(eval(hierarchy.geoName.dataSource)) // works
这可能会吸引 eval() = evil 军队。所以问题是:
鉴于 $scope.geoData 的内容是受控的,eval 的安全问题应该不用担心,对吧?在这种情况下,以这种方式使用 eval() 应该是安全的?
是否还有其他 javascript 延迟获取变量的方法被认为较少 "evil"?
如果 "eval" 在这种情况下不好,还有其他建议吗?
谢谢!
在评论中遵循@Bergi 的建议:
eval is evil here (mostly because it's slow, hard to debug, and the wrong tool)
Instead, return it in a function such as:
'dataSource': function() { return $scope.stateData }
Then, call it with:
loadData(hierarchy.geoName.dataSource())