暴露闭包内的方法

pau*_*aul 14 javascript closures

当我们在闭包内创建一个方法时,它变成了该闭包的私有,并且在我们以某种方式暴露它之前无法访问它.

怎么暴露?

ale*_*lex 16

你可以返回它的引用...

var a = function() {

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

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

};
Run Code Online (Sandbox Code Playgroud)

在jsFiddle上看到它.

您也可以将其绑定到window对象.但我更喜欢上面的方法,否则你通过全局变量(作为window对象的属性)公开它.


use*_*716 8

你需要以某种方式将它传递到外面.

示例: 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!"
Run Code Online (Sandbox Code Playgroud)


Mic*_*man 5

您可以通过在此范围内内部声明闭包的函数或属性来公开它们(可以根据调用而改变)。

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
Run Code Online (Sandbox Code Playgroud)

在此声明的方法可以访问使用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
Run Code Online (Sandbox Code Playgroud)

函数关闭了范围。您想要做的是返回对有权访问所需范围的函数的引用,以便您可以在以后调用它。

如果您需要创建一个稍后调用特定方法的函数,

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

如果范围界定是一个问题,

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);
Run Code Online (Sandbox Code Playgroud)

您可以将其中的大部分内容内联到可读性较差的示例中,

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

setTimeout只是在新范围内演示执行的一种便捷方法。

var ex = new example(2);
var delayed_call = function() {
    return(ex.getDouble());
}
delayed_call(); // == 4
Run Code Online (Sandbox Code Playgroud)