2010-08-04 14 views
21

इस कोड में मैंने कुछ फ़ंक्शन नामक फ़ंक्शन बनाया है। फिर मैंने Function.prototype.apply और कॉल विधियों को संशोधित किया। तो मेरे फ़ंक्शन कोड के बजाय काम कर रहा है मैं अपना इंटरसेप्शन कोड चला रहा हूं (जो एक चेतावनी दिखाता है)। लेकिन न तो "कॉल" और न ही "लागू" प्रत्यक्ष विधि कॉल को रोकता है। क्या यह इसे रोकना संभव है?क्या मैं सीधे नामक फ़ंक्शन को रोक सकता हूं?

Function.prototype.call = function(){alert("call");}; 
Function.prototype.apply = function(){alert("apply");}; 
function someFunction(){} 
window.onload = function(){ 
    someFunction.call(this); //call alert is shown 
    someFunction.apply(this); //apply alert is shown 
    someFunction(); //how can I intercept this? 
} 

उत्तर

27

आप केवल (जैसे, आप सभी फ़ंक्शन कॉल अवरोधन नहीं कर सकता) उसकी जगह पर एक और समारोह की स्थापना करके एक ज्ञात समारोह ओवरराइड कर सकते हैं:

(function() { 
    // An anonymous function wrapper helps you keep oldSomeFunction private 
    var oldSomeFunction = someFunction; 

    someFunction = function() { 
     alert("intercepted!"); 
     oldSomeFunction(); 
    } 
})(); 

ध्यान दें कि, someFunction पहले से ही एलियास गया था कि क्या/इस कोड द्वारा इसे बदलने से पहले किसी अन्य स्क्रिप्ट द्वारा संदर्भित, उन संदर्भों को अभी भी मूल कार्य को इंगित किया जाएगा जो प्रतिस्थापन फ़ंक्शन द्वारा ओवरराइड नहीं किया गया है।

+0

शायद मैं Function.constructor समारोह बदल सकते हैं:

मैं एक ब्लॉग पोस्ट इन सब का निष्कर्ष है। – yilmazhuseyin

+2

@yilmazhuseyin: नहीं, आप नहीं कर सकते। * फ़ंक्शन * कन्स्ट्रक्टर को बदलना आपको केवल 'नया फ़ंक्शन (str)' के साथ बनाए गए कार्यों को ओवरराइड करने की अनुमति देगा। –

+0

हाँ आप सही हैं। फ़ंक्शन न्यू कन्स्ट्रक्टर() {अलर्ट ("ए");}; Function.prototype.constructor = newConstructor; काम नहीं किया। – yilmazhuseyin

2

आप वैश्विक दायरे में फिर से सक्रिय हो सकते हैं और फ़ंक्शन प्रकार की किसी ऑब्जेक्ट को प्रतिस्थापित कर सकते हैं जो आपको "तुम्हारा" नहीं है।

5
Function.prototype.callWithIntercept = function() { 
    alert("intercept"); 
    return this.apply(null, arguments); 
}; 

var num = parseInt.callWithIntercept("100px", 10); 

यह ध्यान देने योग्य है कि जे एस के नए संस्करण में, वहाँ Proxy वस्तुओं आप उपयोग कर सकते हैं लायक है: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

+0

मुझे यह अवरोध विधि पसंद है – Jake

3

इसकी भी संभावना है तो आपको प्रत्यक्ष समारोह को रोक सकता है कहते हैं। इसके लिए आवश्यक है:

  • या तो समारोह Function.prototype.bind द्वारा बनाई गई है और आप समारोह बनाने से पहले Function.prototype.bind अधिलेखित करने के लिए है, या
  • समारोह समारोह() (या नए से बनाई गई है फंक्शन()) और आपको लक्ष्य फ़ंक्शन बनाने से पहले फ़ंक्शन फ़ंक्शन को ओवरराइट करना होगा।

यदि उपरोक्त दो में से कोई भी पूरी की जा सकती, एक प्रत्यक्ष कॉल अवरोधन करने का एकमात्र तरीका लक्ष्य समारोह है, जो एक समारोह है कि द्वारा बनाई गई है के लिए AndyE https://stackoverflow.com/a/3406523/1316480

द्वारा प्रदान समाधान है रैप करने के लिए है कार्यकाल शाब्दिक है और निजी दायरे में छिपा हुआ है, इसके लिए सीधी कॉल को रोकने का कोई तरीका नहीं है। इसलिए हर कार्य लौटे इसके चारों ओर अपने आवरण होगा http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

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