Angular.js: $ eval nasıl çalışır ve vanilya eval'den neden farklıdır?


151

$scope.$evalDirektiflerde sık sık gördüğünüzü merak ediyordum , bu yüzden kaynağı kontrol ettim ve aşağıdakileri buldum rootScope.js:

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

$parsetarafından tanımlanacak görünür ParseProvideriçinde parse.jskendi mini sözdizimi çeşit tanımlamak için görünen, (dosya uzunluğunda 900 hatları).

Sorularım:

  1. Tam olarak ne $evalyapıyor? Neden kendi mini ayrıştırma diline ihtiyacı var?

  2. Düz eski JavaScript evalneden kullanılmıyor?


13
$ eval geçerli kapsamın karşısındaki açısal ifadeyi değerlendirir .
Mark Rajcok

4
BTW $parsedelicesine harika.
Fresheyeball

Yanıtlar:


186

$evalve $parseJavaScript'i değerlendirmeyin; AngularJS ifadelerini değerlendirir . Bağlantılı belgeler, ifadeler ve JavaScript arasındaki farkları açıklar.

S: $ eval tam olarak ne yapıyor? Neden kendi mini ayrıştırma diline ihtiyacı var?

Dokümanlardan:

İfadeler, genellikle {{expression}} gibi ciltlere yerleştirilen JavaScript benzeri kod parçacıklarıdır. İfadeler $ ayrıştırma hizmeti tarafından işlenir.

Çalıştırabileceğinizi sınırlayan JavaScript benzeri bir mini dildir (örneğin, üçlü işleci hariç, kontrol akış ifadeleri yok) ve bazı AngularJS iyiliği (örn. Filtreler) ekler.

S: Düz eski javascript "eval" neden kullanılmıyor?

Çünkü aslında JavaScript'i değerlendirmiyor. Dokümanların dediği gibi:

Eğer ... rastgele JavaScript kodu çalıştırmak istiyorsanız, bunu bir denetleyici yöntemi yapmalı ve yöntemi çağırmalısınız. JavaScript'ten açısal bir ifadeyi değerlendirmek () istiyorsanız, $ eval () yöntemini kullanın.

Yukarıda bağlantılı olan dokümanlar çok daha fazla bilgiye sahiptir.


$ Eval'in aslında JavaScript'i değerlendirmediğini söylediniz, ancak $ eval ("{id: 'val'}") yaparsam bir JS nesnesi alıyorum. (Açısal 1.0.8)
Gabriel

7
@Yappli $evalJavaScript'i değerlendirmez; JavaScript'in daha güvenli bir alt kümesine benzeyen AngularJS ifadelerini değerlendirir. "{id: 'val'}"geçerli bir AngularJS ifadesidir ve geçerli bir JS nesnesi döndürmelidir. İfadeler ve normal JS arasındaki fark için yukarıdaki bağlantıya bakın.
Josh David Miller

1
Güzel cevap ama "örneğin kontrol akış ifadeleri yok" doğru olduğundan emin değilim. Böyle bir şey yapabilirsiniz ... ng-click = "someVal? SomeFunc (someVal): noop" ki bu tamamen geçerli bir açısal ifade
Charlie Martin

@CharlieMartin Belgelerde özellikle "hiçbir kontrol akış ifadesi yok" yazıyor , ancak amacınız geçerli. Ancak, kesinlikle bir ngClick bunu tavsiye etmem; bu tür bir mantık neredeyse kesinlikle denetleyiciye aittir.
Josh David Miller

1
Belgelerin üçlü operatör desteği kasıtlı olarak eklendiğini söylemesi ilginçtir ... github.com/angular/angular.js/blob/master/src/ng/… ng-click sadece basit bir örnekti ve kabul ediyorum bu mantık bir denetleyicide olmalıdır, ancak köşeli parantez gösteriminde üçlü bir operatör kullanmanın yanlış bir şey görmüyorum ve açısal takım açıkçası ya da desteklemiyorlardı. Sanırım bir düzeltme yapılacaksa, bu cevaptan önce dokümanlarda olmalı
Charlie Martin

22

Testten,

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

Ayrıca değerlendirme ifadesi için yerlilerden geçebiliriz.


2

Bence buradaki orijinal sorulardan biri cevaplanmadı. Vanilla eval () kullanılmadığına inanıyorum, çünkü açısal uygulamalar Chrome uygulamaları olarak çalışmaz, bu da eval () 'nin güvenlik nedenleriyle kullanılmasını açıkça engeller.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.