2012-05-07 2 views
1

객체를 만드는 Foo이라는 js에 "클래스"(함수)가 있습니다. 매우 자주 사용되기 때문에 new Foo(something); 대신 Foo(something);이라는 새 인스턴스를 만들 때 new 키 보드를 사용하지 않아야합니다. 새 연산자를 사용하지 않은 경우 새 객체 반환

나는이 파이어 폭스에서 작동있어 :

function Foo(arg) { 
    if (this instanceof Window) 
     return new Foo(arg); 

    //Object construction here. 
    this.bar = "Hello " + arg; 
} 

지금은 단지 함수로 호출하여 푸의 인스턴스를 만들 수 있습니다.

console.log(Foo("World").bar); //Output "Hello World" in console. 

FF에서는 작동하지만 크롬에서는 작동하지 않지만 IE는 아직 테스트하지 않았습니다.

크롬의 문제는 window 어떤 이유로 그것을 제공하기 때문에 크롬에서 작동하지 않습니다 크롬

Uncaught ReferenceError: Window is not defined 

this instanceof DOMWindow을 정말 유형 DOMWindow의 점이다 :

ReferenceError: DOMWindow is not defined 

나는 또한 시도 !(this instanceof Foo)typeof this을 사용하면 항상 "object"이 표시됩니다.

Foo을 모든 브라우저에서 호출 할 때 new 키워드가 생략 된 경우 어떻게 안정적으로 감지 할 수 있습니까?

업데이트 : !(this instanceof Foo) 작동하지 않습니다. 방금 return this을 실제 Foo 기능에 포함 시켰습니다.

+0

'! (this instanceof Foo)'를 사용하면 나에게 적합합니다 (Mac에서는 Chrome, Safari, Firefox). 그 코드는 :'Foo() {console.log (this instanceof Foo)}'는 위의 브라우저에서'Foo()'와'new Foo()'를'true'로 기록 할 것입니다. – ZER0

+0

@ ZER0 예, 방금 작동하지 못하게하는 함수에서 '돌아 오는이'함수를 가지고 있다는 것을 알았습니다. –

답변

2

시험이의 인스턴스 푸 크롬 (20), FF (12), 그리고 IE 8에서 작동하고, 잘 작동합니다되는 :

function Foo(arg) { 
    if (!(this instanceof Foo)) return new Foo(arg); 

    //Object construction here. 
    this.bar = "Hello " + arg; 
} 

var foo = Foo('World'); 
var baz = new Foo('Baz'); 

console.log(foo.bar); 
console.log(baz.bar); 

을 바이올린으로 : http://jsfiddle.net/YSEFK/

+0

그 전에는 저에게 효과가 없었습니다. 그러나 지금 나는 이유를 알아 냈습니다. 나는 함수의 끝에서 길잃은'return this '을 가지고 있었다. 이 일은 훨씬 깔끔한 방법입니다. –

2

테스트하지는 않았지만 이런 식으로 작동할까요?

var realWindow = this; 

function Foo(arg) { 
    if (this === realWindow) 
     return new Foo(arg); 

    //Object construction here. 
    this.bar = "Hello " + arg; 
} 

당신은 realWindow은 어떤 범위의 외부에 선언 물론, this 가능한 충돌을 방지하기 위해 확인해야 할 것입니다.

일반적으로이 인데도 불구하고 입력하는 몇 가지 문자를 저장하지 않는 것이 좋습니다. 그것은 미래 개발자를위한 코드를 난처하게 만들고 일반적으로 좋은 습관이 아닙니다.

+1

그것은 당신이 원하는 것에 달려 있습니다. jQuery와 같은 프레임 워크의 경우 이것은 매우 편안합니다. 항상 $() 대신 new $()를 사용해야하는 경우를 상상해보십시오. – ThiefMaster

+0

@ ThiefMaster, 당신 말이 맞아요. 그것이 내가 "일반적으로"말한 이유입니다. 거의 항상 규칙을 위반하거나 모범 사례가 좋고 권장되는 경우가 있습니다. :) –

+0

그래,이 작품, 고마워. ThiefMaster가 제안했듯이, 어떤 경우에는 의미가 있습니다. –

0

방법 당신이 일을해야 자신의 유형에 대해 현재 인스턴스를 확인하는 것입니다 : (그것은 전역 객체에 대해 확인하려고에서 저장하고, 거의 모든 상황에 맞는 작동

function Foo(...args...) { 
    if (!(this instanceof Foo)) { 
     return new Foo(...args...); 
    } 
    ...do stuff... 
} 

있지만이되지 수도 다른 사람들에게도 의미가 있습니다.)

var a = {}; 
Foo.call(a); 

반환 할 내용은 무엇입니까?내 예제에서는 새로운 Foo 인스턴스를 반환합니다. 이 아닐 수도 있지만은 새 Foo을 생성하려고합니다.

1

조건을 반전하는 것은 어떨까요?

function Foo(arg) { 
    if (!(this instanceof Foo)) 
     return new Foo(arg); 

    //Object construction here. 
    this.bar = "Hello " + arg; 
} 
+0

이 작동하지만 함수의 이름을 반복해야합니다. 물론'arguments.callee'를 사용할 수도 있지만 ES 엄격 모드에서는 작동하지 않습니다. – ThiefMaster

+0

방금 ​​OP가 필요하다고 대답했습니다. 개인적으로 말해서, 나는'Object.create'를 사용하고 새로운 인스턴스에 대해'constructor'을'적용 '하는 것을 선호합니다. 그런 식으로 자신을 반복 할 필요가 없으며, 당신을 위해 일하는 유틸리티 기능을 만들 수도 있습니다. – ZER0

관련 문제