I was curious about the $scope.$eval you so often see in directives, so I checked out the source and found the following in "rootScope.js":
$eval: function(expr, locals) {
return $parse(expr)(this, locals);
},
"$parse" appears to be defined by "ParseProvider" in "parse.js", which appears to define some kind of mini-syntax of its own (the file is 900 lines long).
My questions are:
What exactly is $eval doing? Why does it need its own mini parsing language?
Why isn't plain old javascript "eval" being used?
$eval and $parse don't evaluate JavaScript; they evaluate AngularJS expressions. The linked documentation explains the differences between expressions and JavaScript.
Q: What exactly is $eval doing? Why does it need its own mini parsing language?
From the docs:
Expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}. Expressions are processed by $parse service.
It's a JavaScript-like mini-language that limits what you can run (e.g. no control flow statements, excepting the ternary operator) as well as adds some AngularJS goodness (e.g. filters).
Q: Why isn't plain old javascript "eval" being used?
Because it's not actually evaluating JavaScript. As the docs say:
If ... you do want to run arbitrary JavaScript code, you should make it a controller method and call the method. If you want to eval() an angular expression from JavaScript, use the $eval() method.
The docs linked to above have a lot more information.
From the test,
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);
}));
We also can pass locals for evaluation expression.