2012-01-29 2 views
7

참조 : 동일한 기능을 구현할 수있는 ECMAScript를 5 준수 방법이 있다면 내가 궁금 http://ejohn.org/blog/simple-class-instantiation/존 레식의 간단한 클래스의 인스턴스와 "엄격한 사용"

// makeClass - By John Resig (MIT Licensed) 
function makeClass(){ 
    return function(args){ 
    if (this instanceof arguments.callee) { 
     if (typeof this.init == "function") 
     this.init.apply(this, args.callee ? args : arguments); 
    } else 
     return new arguments.callee(arguments); 
    }; 
} 

. 문제는 엄격한 모드에서 arguments.callee에 액세스하는 것이 더 이상 사용되지 않습니다.

답변

4

나는 이해하고 있듯이 arguments.callee은 엄격한 모드에서 이 아닙니다.은 계속 사용할 수 있습니다. 오히려 으로 삭제되었으며 사용을 시도하거나 예외가 발생한다고 가정합니다.

해결 방법은 모순을 용서하면 명명 된 익명 함수를 사용하는 것입니다. 정말로 "named function expressions"라고 말해야합니다. 예는 :

function someFunc(){ 
    return function funcExpressionName(args){ 
    if (this instanceof funcExpressionName) { 
     // do something 
    } else 
     return new funcExpressionName(arguments); 
    }; 
} 

사용자가 제공하는 이름, 내 예에 funcExpressionName은 어디서나가 적용되는 함수 내 제외한에서 액세스 할 수 있어야하지 않습니다,하지만 불행히도 IE는 다른 생각을 가지고 (당신이 볼 수있는 경우에 당신 Google it) .

예를 들어 귀하의 질문에 대해서는 arguments.callee의 사용이 내 예제에 따라 교체 될 것이므로 전화 기능으로 설정하는 방법을 모르므로 args.callee을 처리하는 방법을 잘 모르겠습니다.

1

John Resig의 원본 ​​코드는 매개 변수없는 생성자와 함께 실패합니다.

var Timestamp = makeClass(); 
Timestamp.prototype.init = function() { 
    this.value = new Date(); 
}; 

// ok 
var timestamp = Timestamp(); 
alert(timestamp.value); 

// TypeError: args is undefined 
var timestamp = new Timestamp(); 
alert(timestamp.value); 

하지만 NNNNNN 에 의해 주어진 다음 줄

this.init.apply(this, args && args.callee ? args : arguments); 
2

위의 아이디어를 사용하여 복구 할 수는 매우 좋다. IE 문제를 피하기 위해 다음 해결책을 제안합니다. 우리는 내부 플래그를 사용하여 // do something 부분 args.callee 참조를 방지 방법

function makeClassStrict() { 
    var isInternal, instance; 

    var constructor = function(args) { 
     // Find out whether constructor was called with 'new' operator. 
     if (this instanceof constructor) { 
      // When an 'init' method exists, apply it to the context object. 
      if (typeof this.init == "function") { 
       // Ask private flag whether we did the calling ourselves. 
       this.init.apply(this, isInternal ? args : arguments); 
      } 
     } else { 
      // We have an ordinary function call. 

      // Set private flag to signal internal instance creation. 
      isInternal = true;           
      instance = new constructor(arguments); 
      isInternal = false;           
      return instance; 
     } 
    }; 

    return constructor; 
} 

참고.

관련 문제