Разоблачение метода, который находится внутри замыкания - PullRequest
14 голосов
/ 10 декабря 2010

Когда мы создаем метод внутри замыкания, он становится закрытым для этого замыкания и недоступен до тех пор, пока мы каким-либо образом не представим его.

Как его можно раскрыть?

Ответы [ 4 ]

16 голосов
/ 10 декабря 2010

Вы можете вернуть ссылку на него ...

var a = function() {

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

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

};

См. На jsFiddle .

Вы также можете связать его с window объектом . Но я предпочитаю метод выше, в противном случае вы предоставляете его через глобальную переменную (являющуюся свойством объекта window).

8 голосов
/ 10 декабря 2010

Вам нужно каким-то образом передать его наружу.

Пример: 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!"
4 голосов
/ 10 декабря 2010

Вы открываете функции или свойства замыкания, внутренне объявляя их в этой области (которая может изменяться в зависимости от вызова).

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

Методы, объявленные в this может обращаться к переменным, объявленным с использованием 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 голосов
/ 31 марта 2017

В целях производительности вы можете вызвать его следующим образом:

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...