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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5033836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:21:08  来源:igfitidea点击:

Adding console.log to every function automatically

javascriptfunctionlogginghook

提问by JRL

Is there a way to make any function output a console.log statement when it's called by registering a global hook somewhere (that is, without modifying the actual function itself) or via some other means?

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

采纳答案by Wayne

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 augmentwill have the additional behavior.

一个缺点是调用后创建的函数augment不会有额外的行为。

回答by Soorena

Proxy Method to log Function calls

记录函数调用的代理方法

There is a new way using Proxyto achieve this functionality in JS. assume that we want to have a console.logwhenever a function of a specific class is called:

在 JS 中有一种使用Proxy实现此功能的新方法。假设我们想要在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 Proxygives you a lot more functionality than to just logging console names.

请记住, usingProxy为您提供了比仅记录控制台名称更多的功能。

Also this method works in Node.jstoo.

这种方法也适用于 Node.js的了。

回答by Sergey Mell

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

回答by Peter Tseng

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

回答by hexicle

Here's some Javascript which replaces adds console.log to every function in Javascript; Play with it on Regex101:

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

$re = "/function (.+)\(.*\)\s*\{/m"; 
$str = "function example(){}"; 
$subst = "$& console.log(\"()\");"; 
$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 很简单,可能不适用于更复杂的函数名称/声明。

回答by Henrik Albrechtsson

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