回答:
以下は、選択した関数でグローバル名前空間のすべての関数を拡張する方法です。
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
が追加の動作を持たないことです。
fn.apply(this, arguments);
にreturn fn.apply(this, arguments);
return
最も内側の関数にaを追加するだけです。
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でも機能し ます。
よりターゲットを絞ったロギングが必要な場合、次のコードは特定のオブジェクトの関数呼び出しを記録します。オブジェクトのプロトタイプを変更して、すべての新しいインスタンスがログを記録するようにすることもできます。for ... inではなく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);
以下は、JavaScriptのすべての関数にconsole.logを追加するJavascriptを置き換えたものです。Regex101でそれを遊んでください:
$re = "/function (.+)\\(.*\\)\\s*\\{/m";
$str = "function example(){}";
$subst = "$& console.log(\"$1()\");";
$result = preg_replace($re, $subst, $str);
それは「素早い汚いハック」ですが、デバッグに役立ちます。多くの関数がある場合、これは多くのコードを追加するので注意してください。また、RegExは単純で、より複雑な関数名/宣言では機能しない可能性があります。
ロードするすべての内容について、実際にconsole.logに独自の関数をアタッチできます。
console.log = function(msg) {
// Add whatever you want here
alert(msg);
}