2010-04-02 8 views
8

उदाहरण के लिए:जावास्क्रिप्ट में eval फ़ंक्शन को ओवरराइड कैसे करें?

(function() { 
     var proxied = window.eval; 
     window.eval = function() { 
     return proxied.apply(this, arguments); 
     }; 
    })(); 

लेकिन इस कोड काम नहीं कर रहा।

+17

यह मुझे थोड़ा डर लगता है आश्चर्य है तुम ऐसा क्यों कर रहा हो सकता है ... – Paddy

+0

अजीब ... क्योंकि "चेतावनी" और अन्य कार्यों के अधिभावी है। – ko1ik

+2

आपका उपयोग केस क्या है? –

उत्तर

8

आप नहीं कर सकते। (वहाँ एक सीमित यह ऐसा करने का तरीका है, लेकिन यह काफी सीमित है और जादू को बनाए रखने नहीं है कि bobince talks about।) (आईई के JScript

eval कम से कम एक प्रमुख कार्यान्वयन में एक असली जावास्क्रिप्ट कार्य नहीं है , कम से कम आईई 7 के माध्यम से नहीं, नए आईई 8 संस्करण का परीक्षण नहीं किया है), इसलिए उस बल्ले से ठीक है जिसे आप परेशानी में चलाने जा रहे हैं, क्योंकि आप apply के माध्यम से मूल को कॉल नहीं कर पाएंगे (यह वास्तव में महत्वपूर्ण नहीं है eval के लिए)।

हाल ECMAScript 5 विनिर्देश विशेष रूप से कठोर मोड में अनुमति नहीं देता है अधिभावी eval, जो मुझे संदेह है वहाँ बहुत अच्छे कारणों यह अधिभावी नहीं लिए हैं कि बनाता है (तुम वहाँ सख्त मोड नहीं का उपयोग कर रहे हैं)।

+2

सख्त मोड एलियासिंग/ओवरराइडिंग 'eval' को अस्वीकार करता है क्योंकि दुभाषिया पहले से ही यह बताने में सक्षम नहीं होगा कि फ़ंक्शन ब्लॉक में' eval' का कोई छुपा उपयोग नहीं था। यदि कोई टेरप (एएसपी। जेआईटी) सुनिश्चित हो सकता है कि किसी फ़ंक्शन में केवल सरल कोड होता है और कोई भी evals नहीं होता है, तो उत्पन्न कोड पर प्रदर्शन की बहुत विस्तृत श्रृंखला होती है। – bobince

+0

@ बॉबन्स: धन्यवाद, जानना अच्छा है। –

+0

डायनामिक बिल्डिंग ExtJs घटकों के लिए Eval उपयोग। । उदाहरण: Ext.data.Connection() अनुरोध ({ ... , सफलता: समारोह (प्रतिक्रिया है, उससे ऑप्ट) { \t eval (response.responseText); \t} }) अवयव पर जमा हो जाती सर्वर। यह कई परियोजनाओं में उपयोग कर रहा है। एक परियोजना विधि में "eval" उपयोग से एक वैश्विक विधि के लिए आने वाले पैरामीटर के रूप में उपयोग मूल्य, अन्य - उपयोग नहीं करते हैं। कार्यक्षमता रखने के लिए मुझे इस कोड की आवश्यकता है। – ko1ik

0

न केवल आपको यह नहीं करना चाहिए, लेकिन मुझे लगता है कि आप शायद नहीं कर सकते हैं। सबसे पहले, eval एक वैश्विक कार्य है, और क्योंकि खिड़की का सदस्य नहीं है (जैसा आपने ऊपर की कोशिश की)। दूसरी बात यह है कि वैश्विक कार्य के रूप में यह अत्यधिक संभावना है कि यह वीएम में कड़ी मेहनत की जाती है और इसे ओवरराइट नहीं किया जा सकता है।

+2

असल में, तीसरे संस्करण के spec (1999) और 5 वें संस्करण spec (2010) दोनों धारा 15.1.2.1 में वैश्विक वस्तु (जो ब्राउज़र में 'विंडो' है) की संपत्ति के रूप में इसे कॉल करते हैं। लेकिन यह सच है कि यह विश्वसनीय रूप से * लागू * नहीं है। –

+0

टीजे सही है, सभी वैश्विक चर विंडो ऑब्जेक्ट के गुण हैं। इसके अलावा, वीएम के लिए कड़ी मेहनत की? कोई वीएम नहीं है, जावास्क्रिप्ट कुछ वीएम बाइट कोड में संकलित नहीं है। अंत में, आप अधिकतर वैश्विक कार्यों या गुणों को ओवरराइड कर सकते हैं, eval बस विशेष है। –

+0

"कोई वीएम नहीं है" - यह काफी गलत है। कई ब्राउज़र्स हमें जेएस वीएम TraceMonkey (फ़ायरफ़ॉक्स) या वी 8 (क्रोम) देखते हैं, वे क्या हैं? वे इंटरपेटर्स नहीं हैं क्योंकि वे जेएस कोड को मशीन कोड में संकलित करते हैं। लेकिन वे तकनीकी रूप से कंपाइलर नहीं हैं क्योंकि वे पूरी मशीन का पर्दाफाश नहीं करते हैं। वे कोड में एक सबसेट (वर्चुअल मशीन) का पर्दाफाश करते हैं। अगर वह वीएम नहीं है ... पृथ्वी पर क्या है? "इवल सिर्फ विशेष है" - आह तो मैं सही था। –

10

eval जादू है। एक 'असली' समारोह के विपरीत, यह फोन करने वाले में पढ़ सकते हैं और लिखने स्थानीय चर:

function foo() { 
    var a= 1; 
    eval('a+= 1'); 
    alert(a); // 2 
} 

एक प्रॉक्सी समारोह के साथ कि eval बदलें और आप एक समस्या है: a+= 1proxied समारोह के दायरे में कार्यान्वित foo के बजाय। बेकार कोड में क्या हो रहा है, इस पर निर्भर करता है कि मूल्यों को गुम होने का कारण बन सकता है, प्रॉक्सी के स्थानीय, आकस्मिक ग्लोबल्स को नुकसान पहुंचा सकता है।

इसलिए, पूरी तरह से काम कर रहे प्रॉक्सी के साथ eval को प्रतिस्थापित करना असंभव है। (साधारण मामलों के लिए जिन्हें स्थानीय लोगों की आवश्यकता नहीं है, आप इसके साथ दूर हो सकते हैं।)

+0

पुन "असंभव", पूरी तरह से काम कर रहे प्रॉक्सी 'माईवल' के साथ eval को प्रतिस्थापित करना संभव है, लेकिन आपको eval --- 'MyEval (_ => eval (_))' – Pacerier

2

मैंने फ़ायरफ़ॉक्स 3.6.2 में यह कोशिश की और यह काम प्रतीत होता है।

मैं FireBug कमांड लाइन में सीधे इस टाइप किया:

var proxied = eval; 
eval = function() { alert("ha"); return proxied.apply(this, arguments);}; 
eval(7); 
+2

यह विश्वसनीय रूप से क्रॉस-ब्राउज़र काम नहीं करता है , और यहां तक ​​कि फ़ायरफ़ॉक्स पर भी, आपके प्रॉक्सी संस्करण में उस जादू को याद किया जाएगा जो बोबन्स के बारे में बात करता है। –

+0

बैच परिभाषित नहीं किया गया है [इस त्रुटि को तोड़ें] eval (7); एफएफ 3.6.3pre – ko1ik

+0

मुझे पता है कि यह * काम * नहीं है। मैं बस इतना कह रहा हूं कि यह काम करता प्रतीत होता है। –

4

हालांकि पोर्टेबल नहीं है, तो निम्न दृष्टिकोण कुछ स्थानों पर जहां यह अन्यथा यह (के रूप में यह ES5 की आवश्यकताओं कि एक को संतुष्ट करता है) प्राप्त किया जा नहीं होगा में काम करता है '। मानक builtin समारोह' एक MemberExpression है, न कि मूल्य और बी में एक संदर्भ के रूप में) यह परिणाम - ES5 #15.1.2)

(function() { 
    var proxied = window.eval 
    with({get eval(){ console.log('eval called'); return proxied }}) { 
    /* client code */ 
    } 
})() 

यह स्पष्ट रूप से ही लागू होता है अगर आप के साथ() बयान एक में ग्राहक कोड लपेट कर सकते हैं; हालांकि कई स्थितियों में, यह कठिन नहीं होना चाहिए। जाहिर है, वही दृष्टिकोण window को अपने सभी 'गुणों और एक गेटर-प्रॉक्सी eval के साथ अन्य ऑब्जेक्ट के साथ छाया कर सकता है।

स्पाइडरमोन्की के get कथन का समर्थन नहीं करने वाले वातावरण ES5 के defineProperty का उपयोग करने में सक्षम हो सकते हैं। खुद को देखो।

+0

इरेटा: स्टैक ओवरफ़्लो पर 'proxied}' – johnjohn

+2

@johnjohn में '}' गुम है, आप परिवर्तनों का सुझाव देने के लिए अन्य लोगों के उत्तरों को संपादित कर सकते हैं। बस भविष्य के संदर्भ के लिए। लेकिन धन्यवाद! फिक्स्ड। (= – ELLIOTTCABLE

+0

बहुत बढ़िया विचार। लेकिन एक भयानक प्रथा प्रतीत होती है। – Oriol

0

शायद मैं सवाल का सही ढंग समझ में नहीं आया है, लेकिन मैं एक myEval() कार्य है कि मूल eval() इसके अंदर बनाकर eval() "ओवरराइड" और myEval() में अतिरिक्त चरण निष्पादित।

function myEval = function(value){ 
    //do your stuff here 
    //for example 
    try { 
     value = eval(value) 
    } catch (error) { 
     console.log(error) 
     value = NaN 
    } 
    return value 
} 
+0

आपको आपके द्वारा पोस्ट किए गए कोड के लिए कुछ स्पष्टीकरण देना चाहिए। –

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

  • कोई संबंधित समस्या नहीं^_^