2013-07-21 7 views
6

क्या जावास्क्रिप्ट एलियासिंग eval अनुमति देता है? निम्न कोड का पहला भाग अप्रत्याशित रूप से व्यवहार करता है (1, 1 प्रदर्शित करता है), लेकिन दूसरा भाग नहीं है (1, 2 प्रदर्शित करता है)। ईसीएमए स्क्रिप्ट या मोज़िला दस्तावेज़ों का संदर्भ उपयोगी होगा, मुझे कोई नहीं मिला।जावास्क्रिप्ट eval alias

<html> 
<script type="application/javascript;version=1.8"> 
    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     var eval2=eval; 
     eval2('var testVar=2'); 
     alert(testVar); 
    })(); 

    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     eval('var testVar=2'); 
     alert(testVar); 
    })(); 
</script> 
</html> 
+1

पहला व्यक्ति का परिणाम अप्रत्याशित कैसे है? –

+0

जब 'eval' aliased नहीं है, तो यह 1, 2 प्रदर्शित करता है, दूसरा फ़ंक्शन देखें। यदि इसकी उम्मीद है, तो क्या आप इस सवाल का जवाब दे सकते हैं? धन्यवाद। – simonzack

+0

हां लेकिन आपने कहा कि पहला व्यक्ति 1 और 2 प्रदर्शित करके अप्रत्याशित रूप से व्यवहार करता है। –

उत्तर

7

आप कर सकते हैं नहीं "उर्फ" eval और यह एक ही तरीके से व्यवहार करने की उम्मीद है। इतना ही आसान। क्यूं कर? eval एक समारोह नहीं है।

क्या हो रहा है कि जब आप eval2 पर कॉल करते हैं, तो आप वैरिएबल "कैश" को वैश्विक चर के साथ काम करने के लिए सेट कर रहे हैं। इसलिए, इसके अंदर एक चर सेट करके, आप एक वैश्विक चर सेट कर रहे हैं। हालांकि, बाहर निकलने पर, परिवर्तनीय "कैश" फ़ंक्शन पर वापस लौटाता है। यही कारण है कि दूसरा alert दिखाता है 1 - वैश्विक चर को फ़ंक्शन स्तर एक द्वारा छायांकित किया जा रहा है।

यह अनुलग्नक ई ECMAScript (जोर मेरा) की (पेज 239)

10.4.2 में उल्लेख किया गया है: संस्करण 5 में, eval समारोह को अप्रत्यक्ष कॉल के रूप में वैश्विक वातावरण का उपयोग दोनों परिवर्तनीय वातावरण और eval कोड के लिए व्याख्यात्मक वातावरण। संस्करण 3 में, अप्रत्यक्ष eval के कॉलर के परिवर्तनीय और शब्दावली वातावरण eval कोड के वातावरण के रूप में इस्तेमाल किया गया था।

पर "में प्रवेश कर Eval कोड" पूरी परिभाषा यदि eval कोड नहीं है, तो वहाँ कोई बुला संदर्भ या है §10.5.2 (पेज 58) (जोर मेरा)

  1. में परिभाषित किया गया है , एक प्रत्यक्ष कॉल (15.1.2.1.1) eval समारोह फिर से मूल्यांकन किया जा रहा
    • निष्पादन संदर्भ Initialise जैसे कि वह था एक वैश्विक निष्पादन संदर्भ 10.4.1.1 में वर्णित के रूप सी के रूप में eval कोड का उपयोग ।
  2. वरना,
    • बुला निष्पादन संदर्भ से ThisBinding रूप में एक ही मूल्य के लिए ThisBinding सेट करें।
    • कॉलिंग निष्पादन संदर्भ के लेक्सिकलइन्वायरमेंट के समान मूल्य के लिए लेक्सिकल एंटरप्राइज़ को सेट करें।
    • कॉल करने योग्य निष्पादन संदर्भ के चरणीय पर्यावरण के समान वैरिएबल एंटरप्राइज़ को सेट करें।
  3. eval कोड सख्त कोड है, तो
    • Let NewDeclarativeEnvironment तर्क के रूप में LexicalEnvironment गुजर बुला का नतीजा हो strictVarEnv।
    • LexicalEnvironment को सख्त VAREnv पर सेट करें।
    • VariableEnvironment को सख्त VAREnv पर सेट करें।
  4. 10,5 में वर्णित के रूप eval कोड का उपयोग कर घोषणा बाइंडिंग प्रारंभ करें।
+1

यदि 'eval' कोई फ़ंक्शन नहीं है, तो क्यों 'चेतावनी (eval)' दिखाता है' फ़ंक्शन eval() {[मूल कोड]} '? – Teemu

+0

आपका पहला भाग गलत है, 'eval' aliasing फ़ायरफ़ॉक्स में काम करता है, और इसमें कोई त्रुटि नहीं है, लेकिन जैसा कि मैं उम्मीद करता हूं। 'Eval2 (चेतावनी (" परीक्षण ")) का प्रयास करें। असल में, ईसीएमए स्पेक का कहना है, "कार्यान्वयन की अनुमति अब उन तरीकों से eval के उपयोग को प्रतिबंधित करने की अनुमति नहीं है जो प्रत्यक्ष कॉल नहीं हैं।" – simonzack

+3

आप मानक को गलत तरीके से पढ़ रहे हैं। 'eval' * * aliased किया जा सकता है, लेकिन फिर यह अलग-अलग काम करेगा। मानक के अन्य हिस्सों को देखें: "* इवल कोड ** अंतर्निहित eval फ़ंक्शन पर प्रदान किया गया स्रोत टेक्स्ट है। ***" (# 10.1), "* या यदि eval code का मूल्यांकन * * प्रत्यक्ष कॉल *** "(# 10.4.2) और अन्य। – DCoder

2

पहले मामले में जब आप eval का उपयोग करते हैं, तो यह फ़ंक्शन स्कोप का उपयोग करता है जिसमें इसे निष्पादित किया जाता है। जब आप evaleval2 पर असाइन करते हैं और फिर उसी कथन को निष्पादित करते हैं, तो ऐसा लगता है कि यह window संदर्भ (वैश्विक दायरा) का उपयोग कर रहा है और फ़ंक्शन संदर्भ नहीं। यही कारण है कि आप पहले मामले में एक ही मूल्य 1 देखें क्योंकि testVar समारोह के अंदर 1 है और window.testVar बाहर 2. है आप को क्रियान्वित करते हुए यह साबित कर सकते हैं नीचे झलकी

<script> 
(function(){ 
     eval('var testVar=1'); 
     alert(window.testVar); 
     var eval2=eval; 

     eval2('var testVar=2'); 
     alert(window.testVar); 
    })(); 

    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     eval('var testVar=2'); 
     alert(testVar); 
    })(); 
</script> 

वास्तव में, प्रति Mozilla Developer Network के रूप में, आप कर सकते हैं ' टी उर्फ ​​eval।

संबंधित मुद्दे