Как я могу получить доступ к локальной области динамически в JavaScript? - PullRequest
20 голосов
/ 01 марта 2009

Если вы хотите использовать глобальные функции и переменные динамически, вы можете использовать:

window[functionName](window[varName]);

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

Этот код работает правильно, но в настоящее время использует eval, и я пытаюсь придумать, как это сделать.

var test = function(){
    //this = window
    var a, b, c; //private variables

    var prop = function(name, def){
        //this = window
        eval(name+ ' = ' + (def.toSource() || undefined) + ';');    

        return function(value){
            //this = test object
            if ( !value) {
                return eval('(' + name + ')');
            }
            eval(name + ' = value;')
            return this;
        };

    };

    return {
        a:prop('a', 1),
        b:prop('b', 2),
        c:prop('c', 3),
        d:function(){
            //to show that they are accessible via to methods
            return [a,b,c];
        }
    };
}();

>>>test
Object
>>>test.prop
undefined
>>>test.a
function()
>>>test.a()
1 //returns the default
>>>test.a(123)
Object //returns the object
>>>test.a()
123 //returns the changed private variable
>>>test.d()
[123,2,3]

Ответы [ 3 ]

8 голосов
/ 01 марта 2009

Чтобы ответить на ваш вопрос, нет, невозможно выполнить поиск динамических переменных в локальной области без использования eval().

Лучшая альтернатива - сделать вашу область видимости обычным объектом [literal] (т. Е. "{}") и вставить туда свои данные.

7 голосов
/ 01 марта 2009

Нет, как crescentfresh сказал. Ниже вы найдете пример того, как реализовать без eval, но с внутренним закрытым объектом.

var test = function () {
  var prv={ };
  function prop(name, def) {
    prv[name] = def;
    return function(value) {
      // if (!value) is true for 'undefined', 'null', '0', NaN, '' (empty string) and false.
      // I assume you wanted undefined. If you also want null add: || value===null
      // Another way is to check arguments.length to get how many parameters was
      // given to this function when it was called.
      if (typeof value === "undefined"){
        //check if hasOwnProperty so you don't unexpected results from
        //the objects prototype.
        return Object.prototype.hasOwnProperty.call(prv,name) ? prv[name] : undefined;
      }
      prv[name]=value;
      return this;
    }
  };

  return pub = {
    a:prop('a', 1),
    b:prop('b', 2),
    c:prop('c', 3),
    d:function(){
      //to show that they are accessible via two methods
      //This is a case where 'with' could be used since it only reads from the object.
      return [prv.a,prv.b,prv.c];
    }
  };
}();
0 голосов
/ 01 марта 2009

Надеюсь, я не слишком упрощен, но как насчет чего-то столь же простого, как использование объекта?

var test = {
    getValue : function(localName){
        return this[localName];
    },
    setValue : function(localName, value){
        return this[localName] = value;
    }
};

>>> test.a = 123
>>> test.getValue('a')
123
>>> test.a
123

>>> test.setValue('b', 999)
999
>>> test.b
999
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...