我对你经常在指令中看到的$scope.$eval
感到好奇,所以我查看了源代码并在rootScope.js
中找到了以下内容:
$eval: function(expr, locals) {
return $parse(expr)(this, locals);
},
$parse
似乎由ParseProvider
中的parse.js
定义,它似乎定义了自己的某种迷你语法(文件长度为900行)。
我的问题是:
$eval
到底在做什么?为什么它需要自己的迷你解析语言?
为什么不使用普通的旧JavaScript eval
?
答案 0 :(得分:181)
$eval
和$parse
不评估JavaScript;他们评估AngularJS expressions。链接的文档解释了表达式和JavaScript之间的差异。
问:$ eval到底在做什么?为什么它需要自己的迷你解析语言?
来自文档:
表达式是类似JavaScript的代码片段,通常放在绑定中,例如{{expression}}。表达式由$ parse服务处理。
这是一种类似JavaScript的迷你语言,它限制了你可以运行的内容(例如,没有控制流语句,除了三元运算符)以及添加一些AngularJS优点(例如过滤器)。
问:为什么不使用普通的旧javascript“eval”?
因为它实际上并没有评估JavaScript。正如文档所说:
如果......您确实希望运行任意JavaScript代码,则应将其设为控制器方法并调用该方法。如果要从JavaScript中使用eval()角度表达式,请使用$ eval()方法。
与上述相关的文档提供了更多信息。
答案 1 :(得分:22)
从测试开始,
it('should allow passing locals to the expression', inject(function($rootScope) {
expect($rootScope.$eval('a+1', {a: 2})).toBe(3);
$rootScope.$eval(function(scope, locals) {
scope.c = locals.b + 4;
}, {b: 3});
expect($rootScope.c).toBe(7);
}));
我们也可以传递本地的评估表达式。
答案 2 :(得分:2)
我认为这里的一个原始问题没有得到解答。我认为没有使用vanilla eval()因为那时有角度的应用程序无法用作Chrome应用程序,因为出于安全考虑,它会明确阻止使用eval()。