2010-12-10 7 views
13

클로저 내부에 메서드를 만들면 해당 클로저에 대해 비공개가되며 어떤 방식 으로든 메서드를 노출 할 때까지 액세스 할 수 없습니다.클로저 안에있는 메서드 공개

어떻게 노출 될 수 있습니까?

답변

15

당신은 ... 그것을

var a = function() { 

    var b = function() { 
     // I'm private! 
     alert('go away!'); 
    }; 

    return { 
     b: b // Not anymore! 
    }; 

}; 

See it on jsFiddle을 참조를 반환 할 수 있습니다.

bind it to the window object 수 있습니다. 하지만 위의 방법을 선호합니다. 그렇지 않으면 전역 변수 (window 개체의 속성 임)를 통해 노출됩니다.

+0

일을. OP,이 전자 책을 확인해야합니다 : http://addyosmani.com/blog/essentialjsdesignpatterns/. 이것을 "모듈 공개"패턴이라고합니다. – simshaun

+0

감사합니다! 익명의 함수 인 경우 동일한 방법으로 노출 할 수 있습니까? – paul

+0

@paul 예,'return function() {}'. – alex

7

어떤 방식으로 외부로 전달해야합니다.

예 :http://jsfiddle.net/patrick_dw/T9vnn/1/

function someFunc() { 

    var privateFunc = function() { 
     alert('expose me!'); 
    } 

    // Method 1: Directly assign it to an outer scope 
    window.exposed = privateFunc; 

    // Method 2: pass it out as a function argument 
    someOuterFunction(privateFunc); 

    // Method 3: return it 
    return privateFunc; 
} 

someFunc()(); // alerts "expose me!" 

function someOuterFunction(fn) { 
    fn(); // alerts "expose me!" 
} 

window.exposed(); // alerts "expose me!" 
+0

+1이 없기 때문에 나는 그것을 하나라고 생각합니다. – alex

+0

창이 글로벌 객체입니다. 전역 개체를 사용하여 메서드를 노출하는 것이 좋은 방법입니까? – paul

+0

@paul - @alex에 동의하고 아니오라고 말합니다. 나는 단지 그것을 일반적인 예로서 사용했다. 액세스 할 수있는 범위에 할당 할 수 있습니다. – user113716

3

당신은 내부적으로 에서 (호출에 따라 변경 될 수 있습니다)이 범위를 선언하여 기능이나 폐쇄의 속성을 노출.

function example(val) { 

    var value = val; 

    this.getVal = function() { 
     return value; 
    } 

    this.setVal = function(v) { 
     value = v; 
    } 
} 

var ex = new example(2); 
ex.getVal(); // == 2 
ex.setVal(4); // == null 
ex.getVal(); // == 4 

방법 선언 VAR를 사용하여 변수에 액세스 할 수 에 선언,하지만 다른 방법으로 '라운드.

function example(val) { 

    var value = val; 

    var double = function(v) { 
     return 2 * v; 
    } 

    this.getDouble = function() { 
     return double(value); 
    } 
} 


var ex = new example(2); 
ex.getDouble(); // == 4 

함수 스코프 위에 닫는다. 당신이하고 싶은 것은 나중에 필요할 때 호출 할 수 있도록 필요한 범위에 대한 액세스 권한이있는 함수에 대한 참조를 반환하는 것입니다.

일부 나중에에서 특정 메소드를 호출하는 함수를 작성해야하는 경우,

범위 지정에 문제가있는 경우
var ex = new example(2); 
var delayed_call = function() { 
    return(ex.getDouble()); // == 4, when called 
} 
setTimeout(delayed_call, 1000); 

,

var ex = new example(2); 
var delayed_call = (function(ex_ref) { 
    return function() { 
     return(ex_ref.getDouble()); // == 4, when called 
    } 
})(ex); // create a new scope and capture a reference to ex as ex_ref 
setTimeout(delayed_call, 1000); 

당신은 적은 비용으로이 대부분의 인라인 수 판독 예

setTimeout((function(ex_ref) { 
    return function() { 
     return(ex_ref.getDouble()); // == 4, when called 
    })(new example(2))) 
    , 1000 
); 

의 setTimeout은 새로운 범위에서 실행을 보여주는 편리한 방법입니다.

var ex = new example(2); 
var delayed_call = function() { 
    return(ex.getDouble()); 
} 
delayed_call(); // == 4 
+0

감사합니다! ... 설명을 위해 ... – paul

0

성능을 위해 당신이 이런 식으로 호출 할 수 있습니다

var a = (function(){ 
    function _a(){} 
    _a.prototype = (function(){ 
    var _test = function(){ console.log("test"); }; 
    return { 
     test: _test 
    } 
    }()); 

    return new _a(); 
}()); 

// usage 
var x = a; 
x.test(); // "test"