2011-02-17 4 views
71

어쨌든 전역 훅을 어딘가에 (즉, 실제 함수 자체를 수정하지 않고) 등록하거나 다른 수단을 통해 호출 할 때 어떤 함수 출력을 console.log 문으로 만들 수 있습니까? ?모든 함수에 console.log를 자동으로 추가하기

+0

훌륭한 질문이지만 이것이 가능한지 알고 싶습니다.하지만 실제로는 그렇지 않을 것이라고 확신합니다 ... 아마도 좋아하는 브라우저의 js 엔진에 기능 요청을 추가 할 수 있습니다. ? :-) – Endophage

+0

완벽한 질문, 나는 이와 비슷한 것이 필요할 것이다 – mjimcua

답변

52

여기 당신의 선택의 기능과 글로벌 네임 스페이스의 모든 기능을 확대하는 방법 :

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를 호출 한 후 생성 된 어떤 기능이 추가 행동이없는 것입니다.

+0

함수의 반환 값을 적절하게 처리합니까? – SunnyShah

+2

@SunnyShah 그렇지 않습니다. http://jsfiddle.net/Shawn/WnJQ5/하지만이 작업은 http://jsfiddle.net/Shawn/WnJQ5/1/에서 작동합니다. 모든 경우 ... 차이점은'fn.apply (this, arguments);를'fn.apply (this, arguments);를 반환하기 위해 변경하는 것 ' – Shawn

+2

@Shawn @SunnyShah Fixed. 가장 안쪽 함수에'return '을 추가하기 만하면됩니다. –

-2

로드하는 모든 것을 실제로 console.log에 연결할 수 있습니다.

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

내 downvote에 대해 설명해야합니까? – vladkras

+0

정확도는 100 %입니다. –

-1

다음은 Javascript의 모든 기능에 console.log를 추가하는 일부 Javascript입니다. Regex101에 함께 재생 :

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

그것은 '신속하고 더러운 해킹'이다하지만 디버깅에 유용 찾을 수 있습니다. 많은 기능을 가지고 있다면 많은 코드가 추가 될 것이기 때문에 조심하십시오. 또한 RegEx는 단순하며 더 복잡한 함수 이름/선언에 대해서는 작동하지 않을 수 있습니다.

1

보다 자세한 대상 로깅을 원하면 다음 코드는 특정 개체에 대한 함수 호출을 기록합니다. Object Prototype을 수정하여 새로운 인스턴스가 모두 로깅되도록 할 수도 있습니다. for ... 대신 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); 
관련 문제