Angular.js : $ eval은 어떻게 작동하며 왜 vanilla eval과 다른가요?


151

$scope.$eval지시문에서 자주 볼 수있는 궁금한 점이 있으므로 소스를 확인하고 다음을 발견했습니다 rootScope.js.

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

$parseParseProviderin parse.js에 의해 정의 된 것으로 보이며, 이는 자체의 어떤 종류의 미니 구문을 정의하는 것으로 보입니다 (파일의 길이는 900 줄입니다).

내 질문은 :

  1. 정확히 $eval뭐하는거야? 왜 미니 구문 분석 언어가 필요한가요?

  2. 왜 평범한 오래된 JavaScript eval가 사용되지 않습니까?


13
$ eval 은 현재 범위와 비교 하여 각도 표현식 평가합니다 .
Mark Rajcok

4
BTW $parse는 대단합니다.
Fresheyeball

답변:


186

$eval$parse자바 스크립트를 평가하지 않는다; AngularJS 표현식 을 평가 합니다 . 링크 된 문서는 표현식과 JavaScript의 차이점을 설명합니다.

Q : $ eval은 정확히 무엇을하고 있습니까? 왜 미니 파싱 언어가 필요한가요?

문서에서 :

표현식은 일반적으로 {{expression}}과 같은 바인딩에 배치되는 JavaScript와 유사한 코드 스 니펫입니다. 식은 $ parse 서비스로 처리됩니다.

JavaScript와 같은 미니 언어로 실행할 수있는 것을 제한하고 (예 : 삼항 연산자를 제외한 제어 흐름 설명 없음) AngularJS의 장점 (예 : 필터)을 추가합니다.

Q : 왜 평범한 오래된 자바 스크립트 "eval"이 사용되지 않습니까?

실제로 JavaScript를 평가하지 않기 때문입니다. 문서에서 말한 것처럼 :

임의의 JavaScript 코드를 실행하려면 컨트롤러 메소드로 만들고 메소드를 호출해야합니다. JavaScript에서 각도 표현식을 eval ()하려면 $ eval () 메소드를 사용하십시오.

위에 링크 된 문서에는 더 많은 정보가 있습니다.


$ eval은 실제로 JavaScript를 평가하지는 않지만 $ eval ( "{id : 'val'}")을 수행하면 JS 객체를 얻습니다. (Angular 1.0.8)
가브리엘

7
@Yappli $eval는 JavaScript를 평가하지 않습니다. JavaScript의 안전한 하위 집합과 비슷한 AngularJS 표현식을 평가합니다. "{id: 'val'}"유효한 AngularJS 표현식이며 유효한 JS 객체를 반환해야합니다. 표현식과 일반 JS의 차이점에 대해서는 위의 링크를 참조하십시오.
Josh David Miller

1
좋은 대답이지만 "예 : 제어 흐름 설명이 없습니다"라는 것이 확실하지 않습니다. 다음과 같은 작업을 수행 할 수 있습니다 ... ng-click = "someVal? someFunc (someVal) : noop"완벽하게 유효한 각도 표현
Charlie Martin

@CharlieMartin이 문서에는 구체적으로 "제어 흐름 설명 없음" 이 나와 있지만 요점은 유효합니다. 그러나 ngClick에서는 그렇게하지 않는 것이 좋습니다. 이러한 종류의 논리는 거의 확실하게 컨트롤러에 속합니다.
Josh David Miller

1
워드 프로세서는 삼항 연산자에 대한 지원이 의도적으로 추가 된로 ... 말할 것은 흥미 github.com/angular/angular.js/blob/master/src/ng/... NG 클릭 그냥 간단한 예제와 내가 동의 그 논리는 컨트롤러에 있어야하지만 대괄호 표기법에서 삼항 연산자를 사용하는 데 아무런 문제가 없으며 각도 팀이 분명히 그렇지 않거나 지원을 추가하지 않았을 것입니다. 나는 수정이 이루어 졌다면,이 답변 전에 문서에서 일어날 것이라고 생각합니다
Charlie Martin

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

나는 여기서 원래의 질문 중 하나가 대답하지 않았다고 생각합니다. 바닐라 eval ()은 각도 앱이 Chrome 앱으로 작동하지 않아 보안상의 이유로 eval ()이 명시 적으로 사용되지 않기 때문에 사용되지 않는다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.