Angular.js: $ eval कैसे काम करता है और यह वेनिला eval से अलग क्यों है?


151

मैं $scope.$evalआपके बारे में उत्सुक था इसलिए अक्सर निर्देशों में देखता हूं, इसलिए मैंने स्रोत की जांच की और निम्नलिखित में पाया rootScope.js:

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

$parseद्वारा परिभाषित किया ParseProviderगया parse.jsप्रतीत होता है, जो अपने आप में कुछ प्रकार के मिनी-सिंटैक्स को परिभाषित करने के लिए प्रकट होता है (फ़ाइल 900 लाइनों लंबी है)।

मेरे प्रश्न हैं:

  1. वास्तव में क्या $evalकर रहा है? इसे अपनी स्वयं की मिनी पार्सिंग भाषा की आवश्यकता क्यों है?

  2. सादे पुराने जावास्क्रिप्ट evalका उपयोग क्यों नहीं किया जा रहा है?


13
$ eval वर्तमान गुंजाइश पर / के खिलाफ एक कोणीय अभिव्यक्ति का मूल्यांकन करता है
मार्क राजकोक

4
BTW $parseपागलपन महान है।
Fresheyeball

जवाबों:


186

$evalऔर $parseजावास्क्रिप्ट का मूल्यांकन न करें; वे AngularJS अभिव्यक्तियों का मूल्यांकन करते हैं । लिंक्ड डॉक्यूमेंट एक्सप्रेशन और जावास्क्रिप्ट के बीच अंतर बताता है।

प्रश्न: वास्तव में $ eval क्या कर रहा है? इसकी अपनी लघु पार्सिंग भाषा की आवश्यकता क्यों है?

डॉक्स से:

अभिव्यक्तियाँ जावास्क्रिप्ट की तरह कोड स्निपेट्स हैं जिन्हें आमतौर पर {{अभिव्यक्ति}} जैसे बाइंडिंग में रखा जाता है। भाव $ पार्से सेवा द्वारा संसाधित होते हैं।

यह एक जावास्क्रिप्ट-जैसी मिनी-भाषा है जो आपके द्वारा चलाए जा सकने वाली सीमाओं (जैसे कि कोई नियंत्रण प्रवाह विवरण नहीं है, टर्नरी ऑपरेटर को छोड़कर) के साथ-साथ कुछ AngularJS अच्छाई (जैसे फ़िल्टर) को जोड़ता है।

प्रश्न: सादा पुरानी जावास्क्रिप्ट "eval" का उपयोग क्यों नहीं किया जा रहा है?

क्योंकि यह वास्तव में जावास्क्रिप्ट का मूल्यांकन नहीं कर रहा है। डॉक्स कहते हैं:

यदि ... आप मनमाना जावास्क्रिप्ट कोड चलाना चाहते हैं, तो आपको इसे एक नियंत्रक विधि बनाना चाहिए और विधि को कॉल करना चाहिए। यदि आप जावास्क्रिप्ट से एक कोणीय अभिव्यक्ति () निकालना चाहते हैं, तो $ eval () विधि का उपयोग करें।

ऊपर दिए गए डॉक्स में बहुत अधिक जानकारी है।


आपने कहा कि $ eval वास्तव में जावास्क्रिप्ट का मूल्यांकन नहीं कर रहा है, लेकिन अगर मैं $ eval करता हूं ("{id: 'val'}") तो मुझे एक JS ऑब्जेक्ट मिलता है। (कोणीय 1.0.8)
गेब्रियल

7
@Yappli $evalजावास्क्रिप्ट का मूल्यांकन नहीं करता है; यह AngularJS अभिव्यक्तियों का मूल्यांकन करता है, जो जावास्क्रिप्ट के एक सुरक्षित उपसमुच्चय की तरह हैं। "{id: 'val'}"एक मान्य AngularJS अभिव्यक्ति है और एक वैध JS ऑब्जेक्ट वापस करना चाहिए। भाव और नियमित JS के बीच अंतर के लिए ऊपर दिए गए लिंक को देखें।
जोश डेविड मिलर

1
अच्छा जवाब है, लेकिन मुझे यकीन नहीं है कि "जैसे कोई नियंत्रण प्रवाह बयान नहीं" सटीक है। आप ऐसा कुछ कर सकते हैं ... एनजी-क्लिक = "someVal? SomeFunc (someVal): noop" जो पूरी तरह से वैध कोणीय अभिव्यक्ति है
चार्ली मार्टिन

@CharlieMartin प्रलेखन विशेष रूप से "कोई नियंत्रण प्रवाह विवरण नहीं" कहता है , लेकिन आपकी बात वैध है। हालाँकि, मैं निश्चित रूप से ऐसा करने की सिफारिश नहीं करूंगा; उस तरह के तर्क लगभग निश्चित रूप से नियंत्रक में हैं।
जोश डेविड मिलर

1
दिलचस्प बात यह है कि डॉक्स का कहना है कि जैसा कि टर्नरी ऑपरेटर के लिए समर्थन जानबूझकर जोड़ा गया था ... github.com/angular/angular.js/blob/master/src/ng/… एनजी-क्लिक केवल एक सरल उदाहरण था और मैं सहमत हूं वह तर्क एक नियंत्रक में होना चाहिए, लेकिन मुझे ब्रैकेट नोटेशन में एक टर्नरी ऑपरेटर का उपयोग करने में कुछ भी गलत नहीं दिखता है और कोणीय टीम स्पष्ट रूप से या तो नहीं करती है या उन्होंने इसके लिए समर्थन नहीं जोड़ा होगा। मुझे लगता है कि अगर कोई सुधार किया जाना था, तो इस उत्तर से पहले डॉक्स में ऐसा होना चाहिए
चार्ली मार्टिन

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

मुझे लगता है कि यहां एक भी मूल प्रश्न का उत्तर नहीं दिया गया था। मेरा मानना ​​है कि वेनिला ईवैल () का उपयोग नहीं किया जाता है क्योंकि तब कोणीय ऐप क्रोम ऐप के रूप में काम नहीं करेंगे, जो स्पष्ट रूप से सुरक्षा कारणों के लिए इवेल () का उपयोग करने से रोकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.