हर फ़ंक्शन को कंसोल.लॉग को स्वचालित रूप से जोड़ना


97

क्या किसी फंक्शन आउटपुट को कंसोल बनाने का एक तरीका है। यह स्टेटमेंट तब दर्ज किया जाता है जब इसे कहीं पर एक ग्लोबल हुक रजिस्टर करके बुलाया जाता है (जो कि वास्तविक फ़ंक्शन को संशोधित किए बिना) या किसी अन्य माध्यम से?


उत्कृष्ट प्रश्न, मुझे यह जानना अच्छा लगेगा कि क्या यह संभव है लेकिन मुझे पूरा यकीन है कि यह नहीं है ... हो सकता है कि आपके पसंदीदा ब्राउज़र के लिए js इंजन में इसे जोड़ने के लिए एक फीचर अनुरोध जोड़ा जाए? :-)
एंडोफेज

बिल्कुल सही सवाल, मुझे कुछ इसी तरह की जरूरत है
mjimcua

जवाबों:


62

यहाँ अपनी पसंद के कार्य के साथ वैश्विक नाम स्थान में सभी कार्यों को बढ़ाने का एक तरीका है:

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];
        if (typeof fn === 'function') {
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    return fn.apply(this, arguments);

                }
            })(name, fn);
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name);
});

एक पक्ष यह है कि कॉल करने के बाद बनाए गए किसी भी कार्य augmentका अतिरिक्त व्यवहार नहीं होगा।


क्या यह फ़ंक्शन के रिटर्न मान को ठीक से संभालता है?
सनीशाह

2
@SunnyShah नहीं यह नहीं है: jsfiddle.net/Shawn/WnJQ5 लेकिन यह एक करता है: jsfiddle.net/Shawn/WnJQ5/1 हालांकि मुझे यकीन नहीं है कि यह सभी मामलों में काम करेगा ... अंतरfn.apply(this, arguments);return fn.apply(this, arguments);
शॉन

2
@ शवन @ सनीशाह फिक्स्ड। बस returnअंतरतम समारोह में एक जोड़ने की जरूरत है ।
वेन

लगभग ठीक काम करता है, लेकिन मुझे इस jquery के साथ एक त्रुटि मिलती है: कॉल: if (jQuery.isFunction (lSrc)) और यह कहता है: TypeError: jQuery.isFunction कोई फ़ंक्शन नहीं है
फ़कीरी पुरुष

4
यह समाधान
वेन

8

मेरे लिए, यह सबसे सुरुचिपूर्ण समाधान की तरह दिखता है:

(function() {
    var call = Function.prototype.call;
    Function.prototype.call = function() {
        console.log(this, arguments); // Here you can do whatever actions you want
        return call.apply(this, arguments);
    };
}());

7

फ़ंक्शन कॉल लॉग करने के लिए प्रॉक्सी विधि

JS में इस कार्यक्षमता को प्राप्त करने के लिए प्रॉक्सी का उपयोग करने का एक नया तरीका है । यह मानकर कि console.logजब भी किसी विशिष्ट वर्ग का कोई कार्य होता है, हम कहते हैं:

class TestClass {
  a() {
    this.aa = 1;
  }
  b() {
    this.bb = 1;
  }
}

const foo = new TestClass()
foo.a() // nothing get logged

हम अपनी कक्षा के तात्कालिकता को एक प्रॉक्सी के साथ बदल सकते हैं जो इस वर्ग की प्रत्येक संपत्ति को ओवरराइड करता है। इसलिए:

class TestClass {
  a() {
    this.aa = 1;
  }
  b() {
    this.bb = 1;
  }
}


const logger = className => {
  return new Proxy(new className(), {
    get: function(target, name, receiver) {
      if (!target.hasOwnProperty(name)) {
        if (typeof target[name] === "function") {
          console.log(
            "Calling Method : ",
            name,
            "|| on : ",
            target.constructor.name
          );
        }
        return new Proxy(target[name], this);
      }
      return Reflect.get(target, name, receiver);
    }
  });
};



const instance = logger(TestClass)

instance.a() // output: "Calling Method : a || on : TestClass"

जांचें कि यह वास्तव में कोडपेन में काम करता है


याद रखें कि उपयोग करने Proxyसे आपको सांत्वना नामों को लॉग करने की तुलना में बहुत अधिक कार्यक्षमता मिलती है।

साथ ही यह तरीका Node.js में भी काम करता है।


क्या आप इंस्टेंस और कक्षाओं का उपयोग किए बिना भी ऐसा कर सकते हैं? विशेष रूप से नोड.जेएस में बोल रहा हूं?
रेवडाईक

@Revadike को इसमें मदद करनी चाहिए: stackoverflow.com/a/28708700/5284370
सोरांए

1

यदि आप अधिक लक्षित लॉगिंग चाहते हैं, तो निम्न कोड किसी विशेष ऑब्जेक्ट के लिए फ़ंक्शन कॉल लॉग करेगा। आप ऑब्जेक्ट प्रोटोटाइप को भी संशोधित कर सकते हैं ताकि सभी नए उदाहरण लॉगिंग भी प्राप्त कर सकें। मैंने इसके बजाय Object.getOwnPropertyNames का उपयोग किया ... इसलिए, यह ECMAScript 6 कक्षाओं के साथ काम करता है, जिनमें असंख्य तरीके नहीं हैं।

function inject(obj, beforeFn) {
    for (let propName of Object.getOwnPropertyNames(obj)) {
        let prop = obj[propName];
        if (Object.prototype.toString.call(prop) === '[object Function]') {
            obj[propName] = (function(fnName) {
                return function() {
                    beforeFn.call(this, fnName, arguments);
                    return prop.apply(this, arguments);
                }
            })(propName);
        }
    }
}

function logFnCall(name, args) {
    let s = name + '(';
    for (let i = 0; i < args.length; i++) {
        if (i > 0)
            s += ', ';
        s += String(args[i]);
    }
    s += ')';
    console.log(s);
}

inject(Foo.prototype, logFnCall);

-1

यहाँ कुछ जावास्क्रिप्ट है जो प्रतिस्थापित करता है। जावास्क्रिप्ट में प्रत्येक फ़ंक्शन के लिए कंसोल जोड़ता है। Regex101 पर इसके साथ खेलें :

$re = "/function (.+)\\(.*\\)\\s*\\{/m"; 
$str = "function example(){}"; 
$subst = "$& console.log(\"$1()\");"; 
$result = preg_replace($re, $subst, $str);

यह एक 'त्वरित और गंदा हैक' है, लेकिन मुझे यह डिबगिंग के लिए उपयोगी लगता है। यदि आपके पास बहुत सारे कार्य हैं, तो सावधान रहें क्योंकि यह बहुत सारे कोड जोड़ देगा। इसके अलावा, RegEx सरल है और अधिक जटिल फ़ंक्शन नाम / घोषणा के लिए काम नहीं कर सकता है।


-10

आप वास्तव में लोड करने वाली हर चीज के लिए कंसोल के लिए अपने स्वयं के फ़ंक्शन को संलग्न कर सकते हैं।

console.log = function(msg) {
    // Add whatever you want here
    alert(msg); 
}

2
सही है या नहीं, यह सवाल का जवाब नहीं देता है। बिल्कुल भी। (किसी को भी भ्रमित किया गया था)
redfox05
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.