자동으로 모든 함수에 console.log 추가


97

어딘가에 (즉, 실제 함수 자체를 수정하지 않고) 전역 후크를 등록하거나 다른 수단을 통해 호출 될 때 함수 출력을 console.log 문으로 만드는 방법이 있습니까?


훌륭한 질문입니다. 이것이 가능한지 알고 싶습니다만, 그렇지 않다고 확신합니다. 좋아하는 브라우저의 js 엔진에 추가 할 기능 요청을 추가 하시겠습니까? :-)
Endophage

완벽한 질문, 나는 이런 비슷한 필요
mjimcua

답변:


62

다음은 선택한 함수로 전역 네임 스페이스의 모든 함수를 확장하는 방법입니다.

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은 호출 후 생성 된 함수 에는 추가 동작이 없다는 것입니다.


함수의 반환 값을 제대로 처리합니까?
SunnyShah

2
@SunnyShah 아니요 : jsfiddle.net/Shawn/WnJQ5 하지만 이건합니다 : jsfiddle.net/Shawn/WnJQ5/1 모든 경우에서 작동할지 모르겠지만 ... 차이점은 다음과 같이 변경 fn.apply(this, arguments);됩니다return fn.apply(this, arguments);
Shawn

2
@Shawn @SunnyShah 고정. return가장 안쪽에있는 함수에 를 추가하기 만하면 됩니다.
Wayne

거의 잘 작동하지만이 jquery : call : if (jQuery.isFunction (lSrc)) 오류가 발생하고 다음과 같이 표시됩니다. : TypeError : jQuery.isFunction is not a function
fekiri malek

4
이 솔루션은 jQuery를 사용하지 않습니다
Wayne

8

나에게 이것은 가장 우아한 해결책처럼 보입니다.

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

7

함수 호출을 기록하는 프록시 메서드

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 에서도 작동합니다 .


인스턴스와 클래스를 사용하지 않고도이 작업을 수행 할 수 있습니까? 특히 node.js에서 말합니까?
Revadike

@Revadike이 도움이 될 것입니다 : stackoverflow.com/a/28708700/5284370
Soorena

1

보다 구체적인 로깅을 원하면 다음 코드는 특정 개체에 대한 함수 호출을 로깅합니다. 모든 새 인스턴스도 로깅되도록 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);

-1

다음은 Javascript의 모든 함수에 console.log를 추가하는 Javascript입니다. Regex101 에서 플레이 하세요 :

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

'빠르고 더러운 해킹'이지만 디버깅에 유용하다고 생각합니다. 기능이 많은 경우 코드가 많이 추가되므로주의하십시오. 또한 RegEx는 간단하며 더 복잡한 함수 이름 / 선언에는 작동하지 않을 수 있습니다.


-10

실제로로드되는 모든 항목에 대해 console.log에 자체 함수를 연결할 수 있습니다.

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

2
맞든 아니든, 질문에 답하지 않습니다. 조금도. (아직도 혼란스러워하는 사람이있는 경우)
redfox05
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.