简体   繁体   English

自动将 console.log 添加到每个函数

[英]Adding console.log to every function automatically

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

Here's a way to augment all functions in the global namespace with the function of your choice:这是一种使用您选择的函数来扩充全局命名空间中的所有函数的方法:

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

One down side is that no functions created after calling augment will have the additional behavior.一个不好的一面是,没有调用后创建的功能augment将有额外的行为。

As to me, this looks like the most elegant solution:对我来说,这看起来是最优雅的解决方案:

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

Proxy Method to log Function calls记录函数调用的代理方法

There is a new way using Proxy to achieve this functionality in JS.在 JS 中有一种使用Proxy实现此功能的新方法。 assume that we want to have a console.log whenever a function of a specific class is called:假设我们希望在调用特定类的函数时有一个console.log

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

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

we can replace our class instantiation with a Proxy that overrides each property of this class.我们可以用覆盖这个类的每个属性的代理替换我们的类实例化。 so:所以:

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"

check that this actually works in Codepen检查这在 Codepen 中是否确实有效


Remember that using Proxy gives you a lot more functionality than to just logging console names.请记住,使用Proxy可为您提供比仅记录控制台名称更多的功能。

Also this method works in Node.js too.这个方法也适用于Node.js。

If you want more targeted logging, the following code will log function calls for a particular object.如果您想要更有针对性的日志记录,以下代码将记录特定对象的函数调用。 You can even modify Object prototypes so that all new instances get logging too.您甚至可以修改对象原型,以便所有新实例也可以记录。 I used Object.getOwnPropertyNames instead of for...in, so it works with ECMAScript 6 classes, which don't have enumerable methods.我使用了 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);

Here's some Javascript which replaces adds console.log to every function in Javascript;这是一些 Javascript,它取代了将 console.log 添加到 Javascript 中的每个函数; Play with it on Regex101 :Regex101上玩它:

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

It's a 'quick and dirty hack' but I find it useful for debugging.这是一个“快速而肮脏的黑客”,但我发现它对调试很有用。 If you have a lot of functions, beware because this will add a lot of code.如果你有很多函数,要小心,因为这会增加很多代码。 Also, the RegEx is simple and might not work for more complex function names/declaration.此外,RegEx 很简单,可能不适用于更复杂的函数名称/声明。

You can actually attach your own function to console.log for everything that loads.对于加载的所有内容,您实际上可以将自己的函数附加到 console.log。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM