어딘가에 (즉, 실제 함수 자체를 수정하지 않고) 전역 후크를 등록하거나 다른 수단을 통해 호출 될 때 함수 출력을 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
은 호출 후 생성 된 함수 에는 추가 동작이 없다는 것입니다.
fn.apply(this, arguments);
됩니다return fn.apply(this, arguments);
return
가장 안쪽에있는 함수에 를 추가하기 만하면 됩니다.
JS에서이 기능을 달성하기 위해 Proxy 를 사용하는 새로운 방법 이 있습니다. 우리가 갖고 싶어한다고 가정 console.log
특정 클래스의 함수가 호출 될 때마다 :
class TestClass {
a() {
this.aa = 1;
}
b() {
this.bb = 1;
}
}
const foo = new TestClass()
foo.a() // nothing get logged
클래스 인스턴스화를이 클래스의 각 속성을 재정의하는 Proxy로 바꿀 수 있습니다. 그래서:
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"
이것이 실제로 Codepen에서 작동하는지 확인하십시오.
를 사용 Proxy
하면 콘솔 이름을 로깅하는 것보다 훨씬 더 많은 기능 을 사용할 수 있습니다.
또한이 방법은 Node.js 에서도 작동합니다 .
보다 구체적인 로깅을 원하면 다음 코드는 특정 개체에 대한 함수 호출을 로깅합니다. 모든 새 인스턴스도 로깅되도록 Object 프로토 타입을 수정할 수도 있습니다. 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);
}