2011-02-17 58 views
71

有沒有辦法做任何功能的輸出時它是由地方(即,不修改實際功能本身)註冊全局鉤子被稱爲的console.log陳述或通過其他手段?添加的console.log各功能自動

+0

優秀的問題,我很想知道這是否可能,但我敢肯定它不是...也許添加一個功能請求,它將被添加到您最喜歡的瀏覽器的js引擎中? :-) – Endophage 2011-02-17 21:13:40

+0

完美的問題,我需要類似這樣的東西 – mjimcua 2015-02-19 10:46:48

回答

52

下面就來增強與您所選擇的功能全局命名空間中的所有功能的方式:

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之後創建的功能將有額外的行爲。

+0

它是否正確處理函數的返回值? – SunnyShah 2012-10-15 19:02:21

-2

實際上,您可以將自己的函數附加到所有加載的console.log中。

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

這裏有一些Javascript代替console.log給Javascript中的每個函數;用它玩上Regex101

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

這是一個「快速和骯髒的劈」,但我覺得它對於調試非常有用。如果你有很多功能,要小心,因爲這會增加很多代碼。此外,正則表達式很簡單,可能無法用於更復雜的函數名稱/聲明。

1

如果您想要更有針對性的日誌記錄,以下代碼將記錄特定對象的函數調用。您甚至可以修改對象原型,以便所有新實例也可以進行日誌記錄。我使用Object.getOwnPropertyNames而不是for ... in,所以它可以與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);