2010-05-03 13 views
12

मेरे पास थोड़ा सा जावास्क्रिप्ट कोड है जो सर्वर-साइड पर कॉन्फ़िगरेशन फ़ाइल में निर्दिष्ट है। चूंकि मैं कॉन्फ़िगरेशन भाषा (लुआ) में एक जावास्क्रिप्ट फ़ंक्शन निर्दिष्ट नहीं कर सकता, इसलिए मेरे पास यह एक स्ट्रिंग है। सर्वर कुछ JSON में स्ट्रिंग वापस आती है और मैं ग्राहक एक सफाई समारोह का उपयोग कर इसे व्याख्या है:फ़ंक्शन स्ट्रिंग को पार्स करने पर जावास्क्रिप्ट eval() "वाक्यविन्यास त्रुटि"

parse_fields = function(fields) { 
    for (var i = 0; i < fields.length; ++i) { 
     if (fields[i].sortType) { 
      sort_string = fields[i].sortType; 
      fields[i].sortType = eval(sort_string); 
     } 
     return fields; 
    } 
}; 

तो बुनियादी तौर पर यह सिर्फ sortType का मूल्यांकन करता है यदि वह मौजूद है। समस्या यह है कि फायरबग eval() लाइन पर "सिंटेक्स त्रुटि" की रिपोर्ट कर रहा है। जब मैं फ़ायरबग कंसोल पर एक ही कदम चलाता हूं, तो यह किसी भी समस्या के साथ काम करता है और मैं जिस समारोह की अपेक्षा करता हूं, मैं इसे निष्पादित कर सकता हूं। मैंने कुछ अलग-अलग बदलावों की कोशिश की है: window.eval सादा eval के बजाय, sortType को संग्रहीत करते हुए, जैसा कि मैंने उपरोक्त किया है, और स्ट्रिंग में छोटी भिन्नताओं को आजमाएं।

fields[i].sortType का नमूना मान "function(value) { return Math.abs(value); }" है।

>>> sort_string 
"function(value) { return Math.abs(value); }" 
>>> eval(sort_string) 
function() 
>>> eval(sort_string)(-1) 
1 

और खुद त्रुटि Firebug में: यहां परीक्षण मैं Firebug कंसोल में किया था है

syntax error 
[Break on this error] function(value) { return Math.abs(value); } 

पिछले बिट है कि प्रासंगिक हो सकता है कि यह सब एक Ext जे एस onReady() समारोह में लपेटा जाता है है, शीर्ष पर Ext.ns नामस्थान परिवर्तन के साथ। लेकिन मुझे लगता है कि window.eval वैश्विक eval को कॉल करेगा, चाहे किसी भी संभावित eval को अधिक विशिष्ट नामस्थानों में ध्यान दिए बिना।

किसी भी विचार की सराहना की जाती है।

+3

ध्यान दें कि आईई कर सकते हैं eval नहीं काम करता है। – SLaks

+0

'var foo = function (value) {...} ' –

+0

@Slaks:' eval' उपर्युक्त स्ट्रिंग के लिए IE में मेरे लिए ठीक काम करता है, कोई त्रुटि नहीं ... जैसा कि eval ("a = function () {वापसी 'बी';} ") '- क्या आप स्पष्ट कर सकते हैं कि आप क्या मतलब चाहते हैं? –

उत्तर

37

कोष्ठक में आप क्या चाहते करने के लिए, लपेट अपने स्ट्रिंग:

a = "function(value) { return Math.abs(value);}"; 
b = eval("("+a+")"); 
b(-1); 
+2

हाँ, यह काम करता है। फायरबग इंटरफ़ेस के बाहर कोड निष्पादित करते समय ब्रांड्स की आवश्यकता क्यों होती है, लेकिन फ़ायरबग कंसोल का उपयोग करते समय आवश्यक नहीं है? –

+0

मैं, एक के लिए, इसे फायरबग कंसोल में भी ब्रेसिज़ के बिना काम नहीं कर सकता। मुझे नहीं पता कि यह आपके लिए क्यों काम करेगा। आप फायरबग का किस संस्करण का उपयोग कर रहे हैं? – Jasper

+1

@ केनी पेंग: मुझे यह एक बार अपने आप को सोचने के लिए याद है और इस सवाल को एक समान प्रश्न के लिए मिला: http://stackoverflow.com/questions/964397/why-does-javascripts-eval-need-parentheses-to-eval-json- डेटा/964,437 # 964,437। जब मैंने सवाल देखा, तो यह मेरा पहला विचार था, @ jhurshman को उनके जवाब के लिए +1। –

4

कोष्ठकों के लिए आवश्यक हैं, क्योंकि वे बात के लिए मजबूर उन्हें अंदर एक अभिव्यक्ति संदर्भ में, जहां यह एक समारोह अभिव्यक्ति होना चाहिए में मूल्यांकन किया जाना ।

कोष्ठकों के बिना, यह बजाय घोषणा एक समारोह हो सकता है, और ऐसा लगता है जैसे कि वह कभी कभी उस तरह से पार्स किया जा रहा है - इस अजीब/असंगत व्यवहार आप का वर्णन कर रहे हैं का स्रोत हो सकता है।

इस समारोह घोषणा की तुलना करें:

function foo(arg) {} 

इस समारोह-अभिव्यक्ति के साथ: अगर यह एक नाम नहीं है

var funcExpr = function foo(arg) {}; 

यह भी है एक समारोह अभिव्यक्ति हो। फ़ंक्शन घोषणाओं के लिए नामों की आवश्यकता होती है।

तो यह, एक वैध घोषणा नहीं है, क्योंकि यह इसके नाम याद आ रही है:

function (arg) {} 

लेकिन यह एक मान्य, अनाम समारोह-अभिव्यक्ति है:

var funcExpr = function(arg) {}; 
संबंधित मुद्दे