Возможно ли динамический доступ к закрытым переменным в шаблоне модуля? - PullRequest
11 голосов
/ 25 декабря 2011

Есть ли способ получить открытую функцию из шаблона модуля для динамического доступа к закрытым переменным? test1 показывает, что я имею в виду под «динамическим доступом», но с открытыми переменными

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(){
            // ??
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2

Я закончил с созданием единственной частной переменной (объекта), хранящей мои личные переменные, чтобы я мог получить к ним доступ таким образом

 privateVarStore[privateVarName]

Но есть ли другое решение для этого?

Ответы [ 2 ]

9 голосов
/ 25 декабря 2011

DEMO

Да.

Извините, что разочаровал Адама Ракиса, но вы можете сделать это с ( зло ) eval:

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(a){
            return eval(a)
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2  -> does return 2

Это одно из тех немногих исключений, где следует использовать eval.

РЕДАКТИРОВАТЬ, согласно предложению (комментарию) Hans B PUFAL, вы можете и должны подтвердитьпараметр в test2 выглядит следующим образом:

test2: function(a){
    return /^[$_a-z][$_a-z0-9]*$/i.test (a) ? eval(a) : undefined;
}
7 голосов
/ 25 декабря 2011

Нет (по крайней мере, не прибегая к eval, согласно ответу qwertymk).

y не является свойством x (рассмотрите возможность присвоения этому объекту имени лучше, чем x, чтобы избежать путаницы с локальной переменной x). y - это локальная переменная, по которой методы x образовали замыкание.

Любой из x методов может получить доступ к y, но не через this.y, а непосредственно через y.

Опять же, y не является собственностью вашего объекта x. Это просто локальная переменная в функции, которая создала x, в результате чего методы x формируют замыкание над ней.

Итак, чтобы получить test2, чтобы вернуть y, просто сделайте:

test2: function(){
    return y;
}

Чтобы создать метод, позволяющий получить доступ к закрытым переменным, рассмотрим что-то вроде этого:

var x = (function () {
    var privateMembers = { x: 0, y: 2, z: 5 };

    return {
        getPrivate: function (name) {
            return privateMembers[name];
        },
        toast: 123,
        test1: function (arg) {
             return this[arg];
        },
        test2: function () {
           // ??
        }
    };
})();

А потом

alert(x.getPrivate("y")); //alerts 2

Проверить эту скрипку

...