2011-12-13 8 views
5

많은 개체와 함수 (개체 메서드)로 구성된 자바 스크립트 응용 프로그램을 개발하고 있습니다. 응용 프로그램의 수명주기에 많은 이벤트를 기록 할 수 있기를 원합니다. 내 문제는 로거 내부에서 어떤 기능이 로그 항목을 호출했는지 알고 싶기 때문에 로그 메시지와 함께 해당 데이터를 저장할 수 있습니다. 즉, 모든 함수가 어떻게 든 자신을 참조 할 수 있어야하므로 해당 참조를 로거에 전달할 수 있습니다. javascript strict 모드를 사용 중이므로 함수 내에 arguments.callee을 사용하면 안됩니다.자체 구현 내에서 함수를 참조하는 방법은 무엇입니까?

다음은 실행할 수있는 매우 간단한 코드 샘플입니다. 단순화를 위해 내 로거 대신 여기 alert을 사용하고 있습니다. 첫 번째 경고에

(function(){ 
"use strict"; 

window.myObject = { 
    id : 'myObject', 
    myFunc : function(){ 
     alert(this.id); // myObject 
     alert(this.myFunc.id); // myFunc - I don't want to do this. I want something generic for all functions under any object 
     alert('???') // myFunc 
     alert(arguments.callee.id); // Will throw an error because arguments.callee in not allowed in strict mode 
    } 
} 
myObject.myFunc.id = 'myFunc'; 

myObject.myFunc(); 
})(); 
  1. - this 두 번째 I 경고에 myFunc
  2. myObject 아니라 관련은 - 나는대로, 내가하고 싶지 않은 그 이름에 의해 기능을 참조 자체 구현 내에서 함수를 참조하는 일반적인 방법을 찾고 있습니다.
  3. 세 번째 경고 - 아이디어가 열려 있습니다.
  4. 네 번째 알림 - 내가하지 않으면 작동했을 것입니다. "use stict";. 나는 더 나은 성능을 제공하고 엄격한 모드를 유지하기를 원하며 훌륭한 코딩 방법을 구성한다.

모든 의견을 부탁드립니다.

는 "엄격 모드"에 익숙하지 않은 경우,이 그것에 대해 읽기 좋은 장소입니다 : JavaScript Strict Mode

답변

4

여기에 그 일을 매우 해키 방법 :

(function(){ 
    "use strict"; 
    window.myObject = { 
     id: 'myObject', 
     myFunc: function() { 
      // need this if to circumvent 'use strict' since funcId doesn't exist yet 
      if (typeof funcId != 'undefined') 
       alert(funcId); 
     }, 
     myFunc2: function() { 
      // need this if to circumvent 'use strict' since funcId doesn't exist yet 
      if (typeof funcId != 'undefined') 
       alert(funcId); 
     } 
    } 
    // We're going to programatically find the name of each function and 'inject' that name 
    // as the variable 'funcId' into each function by re-writing that function in a wrapper 
    for (var i in window.myObject) { 
     var func = window.myObject[i]; 
     if (typeof func === 'function') { 
      window.myObject[i] = Function('var funcId = "' + i + '"; return (' + window.myObject[i] + ')()'); 
     } 
    } 

    window.myObject.myFunc(); 
    window.myObject.myFunc2(); 
})(); 

을 기본적으로, 우리는 그 함수의 이름을 발견 한 후 우리는 문자열에서 각 기능을 재 컴파일하여 '사용 엄격한'선언을 회피하고 있습니다. 이렇게하기 위해 우리는 변수가 'closure'를 통해 함수에 노출되도록 대상 함수의 이름과 동일한 문자열 변수 'funcId'를 선언하는 각 함수를 감싸는 래퍼를 만듭니다.

일을하는 가장 좋은 방법은 아니지만 작동합니다. 또는, 당신은 단순히 내에서 비 ​​엄격한 함수를 호출 할 수 있습니다

(function(){ 
    "use strict"; 

    window.myObject = { 
     id: 'myObject', 
     myFunc: function() { 
      alert(getFuncName()) 
     }, 
     myFunc2: function() { 
      alert(getFuncName()); 
     } 
    } 
})(); 

// non-strict function here 
function getFuncName(){ 
    return arguments.callee.caller.id; // Just fyi, IE doesn't have id var I think...so you gotta parse toString or something 
} 

희망.

+0

고마워요! 그 멋진 솔루션 :) –

0
myFunc : function _myFunc(){ 
    alert(_myFunc); // function 
} 

의 이름을 지정 기능 및 로깅 목적을 해결하기 위해 직접

그들을 참조 진짜 민감한 고유 한 로깅 메시지를 사용하십시오. 라인 정보를 원한다면 예외를 던지십시오.

+1

좀 더 일반적인 것을 찾고 있는데, 항상 각 기능을 해당 이름으로 참조하지 않아도됩니다. 'this'는 컨텍스트를 참조하므로 컨텍스트의 이름을 사용할 필요가 없습니다. –

+0

@OrrSiloni가 존재하지 않습니다. 함수 이름을 사용하십시오. 게다가 모든 기능에는 이름이 있어야합니다. 기억하십시오. – Raynos

+0

함수의 이름을 로거에 전달하지 않아도된다는 생각이 들기 시작했습니다. 누군가가 나를 우아한 해결책으로 놀라게하기를 바란다. –

0

나는 당신이하고 싶은 것을 생각하지 않는다. (현재 함수의 이름을 찾는 것)은 매우 쉽다.

function logger(id){ return function(msg){ 
    return console.log(id, msg); 
};} 

window.myObject = { 
    id : 'myObject', 
    myFunc : function(){ 
     var log = logger('myFunc'); 

     log(1); //prints "Myfunc, 1" 
     log(2); //prints "Myfunc, 2" 
    } 
}; 

이 경찰의 종류 밖으로 만이다 : 당신은 (같은 C에서 __line__ 같은 것들을 수행됩니다) 그러나 아마 조금 OO/마법을 무두질하는 트릭을 수행하는 전처리 단계를 추가로보고 할 수 있습니다 매우 단순하며, ID와 함수 이름을 잘 기억한다면 기억하기 쉬울 것입니다.

+0

좋은 접근 방법이지만 모든 함수의 시작 부분에서 항상 로거를 호출하고 함수의 이름을 문자열로 전달해야합니다.이 함수는 처음부터 피하려고했던 것입니다. –

+0

@OrrSiloni : 알아요.하지만 적어도 한 번만하면되고 익명의 함수 (이름이 없거나 동일한 함수에서 여러 이름이있는 경우)와 작동합니다. – hugomg

관련 문제