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

我很好奇$scope.$eval你经常在指令中看到,所以我检查了源代码并在rootScope.js发现了以下内容:

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

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

我的问题是:

  1. 什么是$eval在做什么? 为什么它需要自己的小parsing语言?

  2. 为什么不是简单的旧的JavaScript eval被使用?

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

问:$ eval在干什么? 为什么它需要自己的小parsing语言?

从文档:

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

这是一种类似JavaScript的迷你语言,它限制了你可以运行的内容(例如,除了三元运算符外没有控制stream程语句),并且增加了一些AngularJS的优点(例如filter)。

问:为什么不是简单的旧的JavaScript“eval”被使用?

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

如果…你确实想运行任意的JavaScript代码,你应该使它成为一个控制器方法并调用方法。 如果您想从JavaScript中eval()angular度expression式,请使用$ eval()方法。

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

从testing中,

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

我们也可以通过当地人评估expression。

我想这里的一个原始问题没有回答。 我相信,香草eval()不使用,因为然后angular应用程序不会作为Chrome应用程序,明确防止eval()出于安全原因使用。