2011-12-13 2 views
5

는이 코드 (JSFiddle)이 "공개"방법의 범위를 올바르게 지정하려면 어떻게해야합니까?

var OBJ = function(){ 
    var privateVar = 23; 
    var self = this; 

    return { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar()); } , 10); 
     } 
    } 

}(); 

alert(OBJ.thePrivateVar()); 

OBJ.thePrivateVarTimeout(); 

이 나는 ​​데 진짜 문제의 추상화가있다.

OBJ.thePrivateVarTimeout()에 대한 호출은 10을 기다린 다음 alert과 23 (다른 노출 된 메서드를 통해 액세스하려고 함)을 기다리게 될 것으로 예상됩니다.

그러나 self이 올바르게 설정되지 않은 것 같습니다. self = this을 설정할 때 this은 함수에 대한 참조가 아니며 전역 개체에 대한 참조 인 것으로 나타납니다. 왜 이런거야?

어떻게 공용 메서드를 만들 수 있습니까? thePrivateVarTimeout은 다른 공용 메서드 thePrivateVar을 호출합니까?

+2

이 * 왜 당신은 일반적으로 기능이? * 호출이기 때문에 .bindAll 방법을 함수

var obj = (function() { var obj = { property: "foobar", timeout: function _timeout() { var that = this; setTimeout(alertData, 10); function alertData() { alert(that.property); } } } return obj; }()); 

var that = this 같은 로컬 값을 사용하거나 사용 포함 것 ('func()'). 이 경우,'this'는 항상 전역 객체를 참조합니다. 빈 객체를 참조하기를 원하면'new'로 호출하거나 하나를 지정하십시오 :'var self = {};'. –

+0

@FelixKling 그러면 '자기'가 올바르게 설정됩니다. 나는 여전히 thePrivateVar를 호출하는데 사용할 수 없다. 나는 레이놀즈의 대답이 내가해야하는 방법이라고 생각한다. –

답변

5
var OBJ = (function(){ 
    var privateVar = 23; 
    var self = { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar); } , 10); 
     } 
    }; 

    return self; 

}()); 

this === global || undefined. ES5에서는 지구 환경이 무엇이든간에 엄격한 ES5에서는 정의되지 않았습니다.

더 일반적인 패턴은

var obj = (function() { 
    var obj = { 
    alertData: function _alertData() { 
     alert(this.property); 
    } 
    property: "foobar", 
    timeout: function _timeout() { 
     setTimeout(this.alertData, 10); 
    } 
    } 

    bindAll(obj) 

    return obj; 
}()); 


/* 
    bindAll binds all methods to have their context set to the object 

    @param Object obj - the object to bind methods on 
    @param Array methods - optional whitelist of methods to bind 

    @return Object - the bound object 
*/ 
function bindAll(obj, whitelist) { 
    var keys = Object.keys(obj).filter(stripNonMethods); 

    (whitelist || keys).forEach(bindMethod); 

    function stripNonMethods(name) { 
     return typeof obj[name] === "function"; 
    } 

    function bindMethod(name) { 
     obj[name] = obj[name].bind(obj); 
    } 

    return obj; 
} 
+0

감사합니다. 첫 번째 패턴을 사용했습니다. 나는'OBJ'에 대한 참조가되기 위해'self'를 실제로 필요로하지 않습니다 - 나는 단지 서로를 부를 수있는 public 메소드가 필요합니다. 그러나 펠릭스는'자기 자신'문제도 언급했다. –

+0

@ElRonnoco 개인적으로'.bindAll' 패턴을 선호합니다. 왜냐하면'that = this'이 눈을 피로 만들기 때문입니다. – Raynos

+1

@Raynos 라인'pd.bindAll (obj)'무엇이'pd'입니까? 또는 pd는 어디에서 유래됩니까? –