Можно ли динамически получать доступ к частным переменным в шаблоне модуля?

Есть ли способ публичной функции из модуля-шаблона получить доступ к закрытым переменным динамически? 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]

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

Ответ 1

DEMO

Да.

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

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

Ответ 2

Нет (по крайней мере, не прибегая к 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

Отметьте эту скрипку