Angular.js:$ eval如何工作?为什么它与vanilla eval不同?

时间:2013-03-27 23:24:52

标签: angularjs

我对你经常在指令中看到的$scope.$eval感到好奇,所以我查看了源代码并在rootScope.js中找到了以下内容:

  $eval: function(expr, locals) {
    return $parse(expr)(this, locals);
  },

$parse似乎由ParseProvider中的parse.js定义,它似乎定义了自己的某种迷你语法(文件长度为900行)。

我的问题是:

  1. $eval到底在做什么?为什么它需要自己的迷你解析语言?

  2. 为什么不使用普通的旧JavaScript eval

3 个答案:

答案 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()。