Javascript 自动向每个函数添加console.log

Javascript 自动向每个函数添加console.log,javascript,function,logging,hook,Javascript,Function,Logging,Hook,在调用任何函数输出时,是否有方法通过在某处注册全局钩子(即,不修改实际函数本身)或通过其他方式使其成为console.log语句?以下是一种使用您选择的函数扩充全局命名空间中所有函数的方法: function augment(withFn) { var name, fn; for (name in window) { fn = window[name]; if (typeof fn === 'function') { win

在调用任何函数输出时,是否有方法通过在某处注册全局钩子(即,不修改实际函数本身)或通过其他方式使其成为console.log语句?

以下是一种使用您选择的函数扩充全局命名空间中所有函数的方法:

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
后创建的函数都不会有额外的行为。

实际上,您可以将自己的函数附加到console.log,以获取加载的所有内容

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

下面是一些Javascript,它取代了将console.log添加到Javascript中的每个函数;玩它在:


这是一个“快速而肮脏的黑客”,但我发现它对调试很有用。如果你有很多函数,要小心,因为这会增加很多代码。此外,正则表达式很简单,可能不适用于更复杂的函数名/声明。

如果您想要更具针对性的日志记录,下面的代码将记录特定对象的函数调用。您甚至可以修改对象原型,以便所有新实例也可以进行日志记录。我使用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);
函数注入(obj,beforeFn){
for(让对象的propName.getOwnPropertyNames(obj)){
设prop=obj[propName];
if(Object.prototype.toString.call(prop)='[Object Function]'){
obj[propName]=(函数(fnName){
返回函数(){
beforeFn.call(this、fnName、参数);
返回prop.apply(这个,参数);
}
})(名称);
}
}
}
函数logFnCall(名称、参数){
设s=name+'(';
for(设i=0;i0)
s+=',';
s+=字符串(args[i]);
}
s+=')';
控制台日志;
}
注入(Foo.prototype,logFnCall);
记录函数调用的代理方法 在JS中,有一种新的使用方法来实现此功能。 假设每当调用特定类的函数时,我们希望有一个
控制台.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中也同样有效。

对我来说,这看起来是最优雅的解决方案:

(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);
    };
}());

很好的问题,我很想知道这是否可能,但我很确定这不是。。。可能会添加一个功能请求,以便将其添加到您喜爱的浏览器的js引擎中?:-)完美的问题,我需要类似的东西,它能正确处理函数的返回值吗?@SunnyShah不,它不能:但这个能:尽管我不确定它在所有情况下都能工作。。。差异正在改变
fn.apply(这是参数)
to
返回fn.apply(这是参数)@Shawn@SunnyShah已修复。只需要在最里面的函数中添加一个
return
。几乎可以正常工作,但是我在这个jquery:call:if(jquery.isFunction(lSrc))中遇到了一个错误,它说:TypeError:jquery.isFunction不是一个函数这个解决方案不使用jQuerycorrect,也不回答这个问题。完全(万一有人还不明白)您也可以在不使用实例和类的情况下执行此操作吗?具体来说,在node.js?@Revadike中,这应该有帮助:
(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);
    };
}());