2010-04-11 3 views
7

콘솔이 존재하지 않을 때 콘솔에 액세스하지 못하게하면서 가능한 한 짧게 로깅 문을 유지하려고했습니다. 나는 다음과 같은 해결책을했다 : 나에게다른 개체에 console.log 할당 (웹킷 문제)

var _ = {}; 
if (console) { 
    _.log = console.debug; 
} else { 
    _.log = function() { } 
} 

, 이것은 매우 우아한 것, 그리고 그것은 (console.debug 더 유용 console.log 이상 할 줄 번호를 유지 포함) 파이어 폭스 3.6에서 잘 작동합니다. 하지만 Safari 4에서는 작동하지 않습니다. [업데이트 : 또는 Chrome에서. 그래서 문제는 방화범이 끌려와 웹킷 콘솔의 차이 것으로 보인다] 나는

console.debug('A') 
_.log('B'); 

과 위의를 수행하면 첫 번째 문은 두 브라우저에서 잘 작동하지만 두 번째는 생성합니다. "형식 오류 : 입력 오류"의를 원정 여행. Firebug와 Safari 웹 개발자 도구가 콘솔을 구현하는 방법과 다른 점이 있습니까? 그렇다면 Apple의 Webkit 부분에 매우 귀찮습니다. 콘솔 함수를 프로토 타입에 바인딩 한 다음 인스턴스에 직접 바인딩하지 않고 인스턴스화하면 도움이되지 않습니다.

물론 console.debug_.log에 할당 된 익명 함수에서 호출 할 수는 있지만 내 줄 번호는 잃어 버릴 수 있습니다. 다른 아이디어?

+0

그것은 웹킷의 특징이다,하지 버그 ;-) https://bugs.webkit.org/show_bug.cgi?id=20141 –

+0

관련 : http://stackoverflow.com/questions/14146316/why-does-scope-reduction-in-safari-break-existing-code – MvG

답변

8

먼저 console이 (예 : IE와 같은 브라우저에서) 정의되지 않으면 오류가 발생합니다. 브라우저에서 전역 객체의 속성으로 확인해야합니다 (window). 일반적으로 기능을 사용하기 전에 기능을 테스트하는 것이 좋습니다. 따라서 debug 메소드에 대한 테스트를 추가했습니다.

은 아마도 Safari에서 console.debug의 구현 this 당신이 _.log ( this 대신 _에 대한 참조가 될 것입니다) 사용하여 호출하는 경우 경우되지 않습니다 console에 대한 참조되는 값에 의존한다. (이것은 내가 질문을 발견하는 방법이다) 나는이 자신에 대한 해결책을 찾고 있었어요

var _ = {}; 
if (typeof window.console != "undefined" 
     && typeof window.console.debug == "function") { 
    _.log = function() { 
     window.console.debug.apply(window.console, arguments); 
    } 
} else { 
    _.log = function() { } 
} 
+3

맞아요, 그건 일반적인 접근 방식이지만 심각한 결함이 있습니다. 번호. 앱의 어디에서나 _.log()를 호출하면 콘솔은 해당 출력을 원본 소스가 아닌 _.log() 함수 내에서 생성 된 것으로보고합니다. 따라서 console.log() 대신 console.debug()를 사용하면 얻을 수있는 이점을 잃게됩니다. –

+2

그럴 경우 별칭이나 래퍼없이'console'을 사용하는 것이 더 쉽지 않을 것이며, 존재하지 않는다면 스텁 메서드로 정의하는 것이 더 쉽지 않을까요? 예를 들어 :'if (typeof window.console! = "undefined") {window.console = {디버그 : function() {}}}'등등. –

+0

당신 말이 맞아, 팀 (typeof window .console == "undefined"'대신'! =', 그렇지?). 필요에 따라 더미 콘솔을 지정하는 대신에 간결성을 위해 내 모험을 포기해야합니다. –

0

: 빠른 테스트를 수행하는 데,이 경우 것으로 보인다 다음과 같은 수정 문제.

Tim이 지적했듯이 웹킷 브라우저 (Safari, Chrome)는이 경우 thisconsole입니다. 그러나 Firefox는 그렇지 않습니다. 따라서 FF에서는 함수를 재 할당하고 행 번호를 유지할 수 있습니다 (그렇지 않으면 모든 로그가 매우 유용하지는 않지만 로깅 함수에서 비롯된 것처럼 보입니다). 어떤 브라우저인지 확인하는 가장 좋은 방법은 브라우저를 사용하여 결과를 확인하는 것입니다. 여기 (커피 스크립트에서) 그것을 확인하는 방법입니다 :

# Check to see if reassigning of functions work 
f = console.log 
assignSupported = true 
try 
    f('Initializing logging...') 
catch e 
    assignSupported = false 

나중에 만들 때 기능 assignSupported을 확인하고 그에 따라 행동 :

levels = 
    ERROR: 1 
    WARN: 2 
    LOG: 3 
    INFO: 4 
    DEBUG: 6 

log.setLevel = (newLevel) -> 
    for label, level of levels 
    if level > newLevel # Skip low levels 
     continue 

    name = label.toLowerCase() 
    f = -> # Fallback - empty function. In Js: var f = function() {} 
    if console?[name] 
     if assignSupported 
     f = console[name] # Wee, we'll have line numbers. 
     else 
     # Webkit need the this of console.log (namely, console) 
     # preserved, so we use a wrapper. 
     # 
     # Calling console[name] within the returned wrapper 
     # makes [name] a subject of the closure, meaning 
     # that it's the last value in the iteration - 
     # we need to preserve it. 
     f = ((n) -> 
      return (-> console[n].apply(console, arguments)))(name) 
    log[name] = f 

log.setLevel levels.DEBUG 

의 선 :

f = ((n) -> 
    return (-> console[n].apply(console, arguments)))(name) 

것은 보일 수를 좀 이상하다. 이는 name이 루프 변수이며 어휘 적으로 바인딩되어 있기 때문에 실행시의 값이 항상 사용됩니다. 이는 마지막으로 level이됩니다.그것은이 자바 스크립트로 컴파일 (경우에 읽기가 쉽다) :

f = (function(n) { 
    return (function() { 
    return console[n].apply(console, arguments); 
    }); 
})(name);