2012-03-07 3 views
4

커스텀 자바 스크립트 라이브러리를 만드는 것에 대해 고민하고 있습니다. 모듈 패턴에 대해 많이 읽었으며 개인 및 공공 회원에 대한 Crockford의 기사도 읽습니다. 나는 즉시 호출 함수 표현식 무엇인지 우리는 그러나자바 스크립트 모듈 패턴, 범위 및 "this"

var myLib = (function() { 
}()) 

같은 물건을 할 이유를 나는 아직도 일반적으로 범위 및 폐쇄에 관한 일부의 경우에 약간의 손실입니다. 구체적인 문제는 다음과 같습니다.

다음 예제는 왜 myLib 객체가 아닌 DOMWindow를 경고합니까? http://jsfiddle.net/slavo/xNJtW/1/

해당 예제의 모든 메소드에서 "this"가 무엇을 의미하는지 설명 할 수 있다면 좋을 것입니다.

+2

FYI :'this'는 변수 범위와 관련이 없습니다. 함수의 호출 컨텍스트와 만 관련됩니다. 그 값은 함수가 호출되는 방법 *에 달려 있습니다. –

+3

BTW, 이런 종류의 상황에서 "this"를 윈도우가 아닌 정의되지 않게하려면 "strict"를 사용할 수 있습니다. 이런 종류의 오류를보다 명확하게 표시하는 데 많은 도움이 될 수 있습니다. – hugomg

답변

3

다음과 같이 this 당신이 다음 방법 중 하나를 따를 수 '인 myObject'의 인스턴스를 개인 기능을 작성하고 액세스하려면 윈도우 객체

function anyFunc(){ 
    alert(this); // window object 
} 

anyFunc(); 


var anyFunc2 = function(){ 
    alert(this); // window object 
} 

anyFunc2(); 

될 것입니다

module = (function() { 

    var privateFunc = function() { 
     alert(this); 
    } 

    var myObject = { 
     publicMethod: function() { 
      privateFunc.apply(this); // or privateFunc.call(this); 
     } 
    }; 

    return myObject; 
}()); 


module.publicMethod(); 

module = (function() { 

    var _this; // proxy variable for instance 

    var privateFunc = function() { 
     alert(_this); 
    } 

    var myObject = { 
     publicMethod: function() { 
      privateFunc(); 
     } 
    }; 
    _this = myObject; 
    return myObject; 
}()); 


module.publicMethod(); 

다음은 귀하의 문제에 대한 해결책입니다. 프로토 타입 기반 객체를 사용하는 것이 좋습니다.

편집 :

첫 번째 방법을 사용할 수 있습니다.여기 myObject 사실

privateFunc 같은 범위에 있고 직접 실제 시나리오는 다음과 같습니다 this에 프록시를 사용할 수 있던 기능

var privateFunc = function() { 
    alert(myObject); 
} 

내에서 사용할 수 있습니다. call도 사용할 수 있습니다.

Module = function() { 

    var _this; // proxy variable for instance 

    var privateFunc = function() { 
     alert(this + "," + _this); 
    } 

    this.publicMethod = function() { 
     privateFunc(); // alerts [object Window],[object Object] 
     privateFunc.call(this); // alerts [object Object],[object Object] 
    } 

    _this = this; 
    return this; 
}; 

var module = new Module(); 
module.publicMethod(); 
+0

왜'_this'를 만드나요? 객체 내부에서'this'는'obj.foo()'와 같은 객체를 참조해야합니다. – Sarfraz

+0

"내부 객체"라는 질문에 답이 있습니다. 여기서'privateFunc'가'myObject' 안에 있지 않다는 것을 알 수 있습니다. 이것은'myObject'의 함수로 정의되지 않았 음을 의미합니다. 따라서 프록시 변수를 사용해야합니다. – Diode

+0

'myObject'의 모든 함수에서 도트 연산자를 사용하여 호출 할 때'thisObject'는'myObject'가됩니다. 예를 들면 : myObject.publicMethod(); – Diode

-1

연결된 피들에서 "this"키워드는 "새로운"키워드 또는 다른 컨텍스트 변경에 의해 절대로 변경되지 않으므로 여전히 글로벌 창 개체를 참조합니다.

편집 : myPrivateMethod은 MYLIB의 구성원인지 설명

+2

* ""this "는"새 "키워드로 변경되지 않으므로 전역 창 개체를 참조합니다. '* 완전히 잘못되었습니다. –

+0

@ amnotiam 어떻게/왜 잘못 되었습니까? 나는 단지 모욕을당하는 대신 뭔가를 배우고 싶습니다 : P – jbabey

+0

* ""this "는"새로운 "키워드로 결코 변경되지 않습니다 ..."* "never"라는 단어를 제거하고 "always"로 바꿉니다. * "... 또는 다른 범위 변경 ..."*'new'는 범위 변경을 일으키지 않습니다. 그것은 호출 컨텍스트 ('this')가 변경되도록합니다. * "... 그래서 그것은 글로벌 윈도우 객체를 참조합니다."* 'this'는 언제 전역 윈도우 객체를 참조합니까? 'new'를 사용할 때? 이 경우 결코 글로벌을 참조하지 않습니다. 그것 이외에는 함수가 어떻게 호출되는지에 달려 있습니다. 미안하다. 모욕감을 느낀다. –

0
를 명시 적으로 언급 할 필요가

:

function MyLib() 
{ 
    this._myPrivateField = "private"; 
    this._myPrivateMEthod = function() 
    { 
     alert(this); // Alerts MyLib function; 
    } 
} 

var libObject = new MyLib(); 

그냥 인클로저 기술을 사용하지 않고, 자바 스크립트에서 아무것도 이제까지 진정으로 개인 없다는 것을 기억!

function MyLib(instanceName) 
{ 
    this.name = instanceName; 
} 

MyLib.prototype.myPrivateFunction() 
{ 
    alert(this); 
} 

그 후 메소드를 호출하려면 :

위 할 수있는 더 좋은 방법은 지금처럼

var libObject = new MyLib(); 
libObject.myPrivateMethod(); // Alerts info about libObject. 
+0

이 경우 공개 메서드 (내 샘플에서 반환 된 개체의 멤버)에서 개인 메서드를 어떻게 호출 할 수 있습니까? – Slavo

+1

왜 후자를 사용하는 것이 더 낫습니까? –

+0

죄송합니다. 포함 할 위의 편집! –

0

모듈 패턴에 대해 기억해야 할 것은 그것을 실행한다는 것입니다 번 완료됩니다. 여전히 호출 할 수있는 메소드는 클로저입니다. 모듈을 만들 때 "this"는 윈도우를 참조하고 값으로 대체되었습니다. 선언 (어디서나) 및 호출하는 함수 내부

관련 문제