有没有办法动态地在AngularJS控制器中的字符串中注入存储的JavaScript代码?
var dynamicJS = "function DoSomething(value){var x = 1+1 return 2;}"
我必须动态地将上面的函数注入到我的AngularJS控制器中,并在下拉列表的选择更改时调用它,其值被绑定到AngularJS控制器。原因是JavaScript函数会根据我在应用程序级别配置的每一行数据而有所不同。我知道我们可以使用$eval
但是想获得一些更好的方法,如果有的话。
任何人都可以对此有任何想法吗?
注意:我使用的是AngularJS v1.4.5
答案 0 :(得分:2)
有多种方法可以实现这一目标。
创建一个Function,将一个参数(即 value )和 functionBody 作为参数传递:
var dynamicJS = "var x = 1+1; return 2;"
var DoSomething = new Function("value", dynamicJS );
var dynamicJS = "function DoSomething(value){var x = 1+1 return 2;}"\
eval(dynamicJS);
因为你在评论中提到了
“它是内部网应用程序而不是外部世界。此请求没有任何问题。”
这可能没问题,但请阅读以下部分。
来自this section of the MDN documentation about eval():
不要不必要地使用eval!
eval()
是一个危险的函数,它使用调用者的特权执行它传递的代码。如果您使用可能受恶意方影响的字符串运行eval()
,则最终可能会使用您的网页/扩展程序的权限在用户的计算机上运行恶意代码。更重要的是,第三方代码可以看到eval()
被调用的范围,这可能导致类似Function
不易受影响的可能攻击。
eval()
通常也比替代品慢,因为它必须 调用JS解释器,而许多其他构造由现代JS引擎优化。对于常见用例,
eval()
有更安全(更快!)的替代方案。 2
参见下面使用的这些技术的演示。单击与每种技术相对应的按钮以查看控制台上的输出。
var dynamicJS = "function DoSomething(value){var x = 1+1; return 2;}"
var functionBody = "var x = 1+1; return 2;";
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('eval').addEventListener('click', function() {
eval(dynamicJS);
console.log('DoSomething(3) -> ',DoSomething(3));
});
document.getElementById('function').addEventListener('click', function() {
var dynamicFunction = new Function("value", functionBody);
console.log('dynamic function(3) ->',dynamicFunction(3));
});
});
<button id="eval">click to eval</button>
<button id="function">click to use Function</button>
1 <子> https://stackoverflow.com/a/4599946/1575353 子>
2 <子> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don“t_use_eval_needlessly!子>
答案 1 :(得分:2)
我相信更简单的方法是解析String然后使用函数构造函数。
这样的事情:
var DoSomething = new Function('value', 'var x = 1+1 return 2');
答案 2 :(得分:1)
也许尝试类似:
function myFunc(obj){
var param = obj.hasOwnProperty('param') ? obj.param : undefined;
console.log(param);
}
var funcString = "myFunc({ param: 'something' });",
Construct = new Function(funcString);
Construct();
说实话没有对它进行测试......但这样就避免了eval()
。