153

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

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

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

我的问题是:

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

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

4

3 回答 3

187

$eval并且$parse不要评估 JavaScript;他们评估 AngularJS表达式。链接的文档解释了表达式和 JavaScript 之间的区别。

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

从文档:

表达式是类似 JavaScript 的代码片段,通常放置在 {{ expression }} 等绑定中。表达式由 $parse 服务处理。

它是一种类似 JavaScript 的迷你语言,它限制了您可以运行的内容(例如,没有控制流语句,除了三元运算符)以及添加了一些 AngularJS 的优点(例如过滤器)。

问:为什么不使用普通的旧javascript“eval”?

因为它实际上并没有评估 JavaScript。正如文档所说:

如果...您确实想运行任意 JavaScript 代码,则应将其设为控制器方法并调用该方法。如果要从 JavaScript eval() 角度表达式,请使用 $eval() 方法。

上面链接的文档有更多信息。

于 2013-03-27T23:36:09.777 回答
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);
}));

我们也可以传递局部变量来进行求值表达式。

于 2013-12-16T15:45:02.257 回答
2

我认为这里的原始问题之一没有得到回答。我相信不使用普通的 eval() 是因为 Angular 应用程序不能像 Chrome 应用程序一样工作,这会出于安全原因明确阻止使用 eval() 。

于 2015-08-26T22:53:01.423 回答