Angular.js: $eval 是如何工作的,为什么它不同于香草 eval?

我对指令中经常出现的 $scope.$eval很好奇,所以我查看了它的源代码,在 rootScope.js中发现了以下内容:

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

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

我的问题是:

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

  2. 为什么没有使用普通的旧 JavaScripteval

128673 次浏览

$eval$parse不计算 JavaScript,它们计算 AngularJS表情。链接的文档解释了表达式和 JavaScript 之间的区别。

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

来自文件:

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

这是一个类似 JavaScript 的迷你语言,它限制了你可以运行的内容(例如,没有控制流语句,除了三元操作符) ,同时增加了一些 AngularJS 的优点(例如过滤器)。

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

因为它实际上不是在评估 JavaScript,正如文档所说:

如果... ... 您确实希望运行任意的 JavaScript 代码,那么应该将其设置为控制器方法并调用该方法。如果希望从 JavaScript 中 eval ()一个角表达式,请使用 $eval ()方法。

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

从测试来看,

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);
}));

我们还可以为求值表达式传递局部变量。

我认为最初的一个问题没有得到解答。我认为不使用香草 eval ()是因为那样的话,有棱角的应用程序就不能像 Chrome 应用程序那样工作,因为 Chrome 应用程序明确地阻止 eval ()被用于安全原因。