2010-01-21 25 views
7

मुझे एक अजीब सवाल है कि मुझे किसी अन्य जावास्क्रिप्ट फ़ंक्शन में कुछ जावास्क्रिप्ट इंजेक्ट करने की आवश्यकता है। मैं एक ढांचे का उपयोग कर रहा हूं जो लॉक है इसलिए मैं मौजूदा फ़ंक्शन को नहीं बदल सकता।जावास्क्रिप्ट फ़ंक्शन में जावास्क्रिप्ट को इंजेक्ट करें

मैं क्या मिल गया है

समारोह DoSomething() कुछ इस तरह { ... }

... ***

मैं है *** (उपर्युक्त) में हेरफेर करें, हालांकि मैं कुछ काम नहीं कर सकता ... इसके बजाय मुझे कुछ कोड के अंत में कोड की कुछ पंक्तियों को इंजेक्ट करने की आवश्यकता है।

मुझे ऐसा करने की आवश्यकता है कि कस्टम फ्रेमवर्क कॉल कुछ() और परिणामस्वरूप सर्वर से लौटाए जाने वाले आईडी में परिणामस्वरूप मुझे निकालने की आवश्यकता है। इस आईडी को केवल कुछ काम करने के अंदर संदर्भित किया जाता है, इसलिए जब तक मैं उस फ़ंक्शन पर कोड इंजेक्ट नहीं करता तब तक मैं इसे तब तक नहीं पकड़ सकता (जब तक कि मुझे कुछ याद नहीं आया)।

क्या ऐसा करने का कोई तरीका है?

+3

फ़ंक्शन 'लॉक' कैसे होता है? – Lazarus

+0

संभावित डुप्लिकेट [क्या फ़ंक्शन के साथ सभी जावास्क्रिप्ट विधियों को लपेटने का कोई तरीका है?] (Http://stackoverflow.com/questions/3919134/is-there-a-way-to-wrap-all-javascript-methods- साथ-साथ-फ़ंक्शन) –

उत्तर

0

कार्य जावास्क्रिप्ट में प्रथम श्रेणी मान हैं, जिसका अर्थ है कि आप उन्हें चर में संग्रहीत कर सकते हैं (और वास्तव में, एक नामित फ़ंक्शन घोषित करना अनिवार्य रूप से एक चर के लिए एक अज्ञात फ़ंक्शन असाइन करना है)। (लेकिन, मैं गलत हो सकता है मेरे जावास्क्रिप्ट कुछ पुरानी है।।;)

function doSomething() { ... } 

var oldVersionOfFunc = doSomething; 
doSomething = function() { 

    var retVal = oldVersionOfFunc.apply(oldVersionOfFunc, args); 

    // your added code here 

    return retVal; 
} 

)

+1

यदि मुझे सही प्रश्न मिल गया है, तो यह यहां सहायता नहीं करेगा, क्योंकि समस्या स्थानीय चर के मान को निकालने के लिए है जिसे केवल 'doSomething' के अंदर संदर्भित किया गया है। और 'doSomething' का नया संस्करण पुराने के अंदर चर का संदर्भ नहीं दे सकता है। –

5

उर्फ ​​यह:

आप इस तरह कुछ करने के लिए सक्षम होना चाहिए।

var oldDoSomething = doSomething; 
doSomething = function() { 
    // Do what you need to do. 
    return oldDoSomething.apply(oldDoSomething, arguments); 
} 
+0

उसे मूल चर – Matt

0

मैं DoSomething समारोह को बदल नहीं सकते ... इसके बजाय मैं किसी भी तरह DoSomething कोड

अंत में कुछ लाइनें इंजेक्शन के अंत में कोड की कुछ लाइनें इंजेक्षन करने की जरूरत है doSomething कोड के लिए doSomething फ़ंक्शन को बदलने जैसा लगता है। मुझे लगता है, दुर्भाग्य से, कि आप खराब हो गए हैं।

(मैं यह सब पर थोड़ा धुंधला हूँ, लेकिन मुझे लगता है कि कार्यों कैसे लोग हैं, जो इस तरह की चीजों के बारे में चिंता जावास्क्रिप्ट में छिपा जानकारी लागू, ठीक है क्योंकि आप उन्हें बाहर से उनके कार्यक्षेत्र उपयोग नहीं कर सकते हैं।)

1
function doSomething() { ... } 
var oldVersionOfFunc = doSomething; 
doSomething = function() { 
    var retVal = oldVersionOfFunc.apply(oldVersionOfFunc, args); 
    // your added code here 
    return retVal; 
} 

यह (बहुत ज्यादा प्रत्यावर्तन)

function doSomething(){ document.write('Test'); return 45; } 
var code = 'myDoSomething = ' + doSomething + '; function doSomething() { var id = myDoSomething(); document.write("Test 2"); return id; }'; 
eval(code) 
doSomething(); 

एक त्रुटि भड़काने के लिए लगता है यह मेरे लिए काम करता है, भले ही यह बदसूरत है।

2

मुझे यकीन नहीं है कि "लॉक" से आपका क्या मतलब है - जावास्क्रिप्ट आपके ब्राउज़र द्वारा व्याख्या किया गया है। भले ही इसे छोटा या एन्कोड किया गया हो, फिर भी आप उस फ़ंक्शन के स्रोत को स्क्रिप्ट के पृष्ठ के स्रोत से कॉपी कर सकते हैं। उस बिंदु पर, आप मूल फ़ंक्शन को अपने स्वयं के डिज़ाइन में पुन: असाइन करते हैं, जिसमें प्रतिलिपि कोड और स्वयं का होता है।

var id; 
var myFunction = function() { 
    // code copied from their source, which contains the variable needed 

    // insert your own code, such as for copying the needed value 
    id = theirIDvalue; 

    // return the value as originally designed by the function 
    return theirValue; 
}; 

theirObject.theirFunction = myFunction; 
3

आपकी सभी प्रतिक्रियाओं के लिए धन्यवाद। प्रत्येक जवाब ने मुझे एक सुराग दिया और जैसा कि मैंने निम्नलिखित समाधान के साथ आ गया है।

<body> 
<script type="text/javascript"> 
    var val; 
    function doSomething(item1, item2) { 
     var id = 3; 
    } 
    function merge() { 
     var oScript = document.createElement("script"); 
     var oldDoSomething = doSomething.toString(); 
     oScript.language = "javascript"; 
     oScript.type = "text/javascript"; 
     var args = oldDoSomething.substring(oldDoSomething.indexOf("(") + 1, oldDoSomething.indexOf(")")); 
     var scr = oldDoSomething.substring(oldDoSomething.indexOf("{") + 1, oldDoSomething.lastIndexOf("}") - 1); 
     var newScript = "function doSomething(" + args + "){" + scr + " val = id; }"; 
     oScript.text = newScript; 
     document.getElementsByTagName('BODY').item(0).appendChild(oScript); 
    } 

    merge(); 

</script> 
<input type="button" onclick="doSomething();alert(val);" value="xx" /> 

+1

पर एक चर के लिए उपयोग की आवश्यकता है एक बेहतर समाधान (डीओएम मैनिपुलेशन की आवश्यकता नहीं है, शुद्ध जावास्क्रिप्ट है): http://stackoverflow.com/a/9134757/39722 –

1

स्रोत कोड तार के साथ काम करके समारोह फेरबदल काफी सरल हो सकता है। एक विशिष्ट उदाहरण के लिए यह करने के लिए, कोशिश:

eval(doSomething.toString().replace(/}\s*$/, ' return id; $&'); 

अब doSomething रिटर्न आईडी। मैं आम तौर पर eval का प्रशंसक नहीं हूं, लेकिन स्थानीय चर का उपयोग करने की आवश्यकता के कारण सामान्य aspect oriented programming तकनीकें यहां लागू नहीं होती हैं। doSomething पहले से ही एक मान देता है

हैं, तो कोशिश:

eval(doSomething.toString().replace(/}\s*$/, ' window.someID = id; $&'); 

एक समारोह में इस चालू करने के लिए, हम कोड वैश्विक क्षेत्र में मूल्यांकन करने की जरूरत है:

function insertCode(func, replacer, pattern) { 
    var newFunc = func.toString().replace(pattern, replacer); 
    with (window) { 
     eval(newFunc); 
    } 
} 
function after(func, code) { 
    return insertCode(func, function (old) { code + old }, /}\s*$/); 
} 
... 
after(doSomething, 'return id;'); 

आप के पुनर्लेखन के लिए चाहते हैं विधियों और अज्ञात कार्यों को चर से बंधे, insertCodeBefore को बदलें:

function insertCode(funcName, replacer, pattern) { 
    var newFunc = eval('window.' + funcName).toString().replace(pattern, replacer); 
    eval('window.' + funcName + '=' + newFunc); 
} 
... 
function Foo() {} 
Foo.prototype.bar = function() { var secret=0x09F91102; } 
... 
after('doSomething', 'return id;'); 
after('Foo.prototype.bar', 'return secret;'); 

ध्यान दें कि कार्यों के लिए पहला तर्क अब तार हैं। हम अन्य कार्यों को परिभाषित कर सकते हैं:

function before(func, code) { 
    return insertCode(func, function (old) {old + code}, /^function\s+\w+\([^)]*\)\s+{/); 
} 
function around(func, beforeCode, afterCode) { 
    before(func, beforeCode); 
    after(func, afterCode); 
} 
+0

यह काम नहीं करेगा सामान्य मामले में क्योंकि फ़ंक्शन किसी भी समय पहले रिटर्न निष्पादित कर सकता है, इसलिए इंजेक्शन कोड तक नहीं पहुंच सकता है। –

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