Exposing a method which is inside a closure

前端 未结 4 545
栀梦
栀梦 2021-02-07 11:21

When we are creating a method inside a closure it becomes private to that closure and can\'t be accessed until we expose it in some way.

How can it be exposed?

4条回答
  •  失恋的感觉
    2021-02-07 11:53

    You expose functions or properties of a closure by internally declaring them in this scope (which can change depending on invocation).

    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
    

    Methods declared in this can access variables declared using var, but not the other way 'round.

    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
    

    The function closes over the scope. What you want to do is to return a reference to a function that has access to the scope you require so you can invoke it at a later point.

    If you need to create a function that calls a specific method at some later point,

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

    If scoping is an issue,

    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);
    

    You can inline most of this with the less readable example of,

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

    setTimeout is just a convenient way of demonstrating execution in new scope.

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

提交回复
热议问题