Как написать этот код JavaScript без Eval? - PullRequest
3 голосов
/ 08 апреля 2010

Как написать этот код JavaScript без eval?

var typeOfString = eval("typeof " + that.modules[modName].varName);
if (typeOfString !== "undefined") {
  doSomething();
}

Дело в том, что имя переменной, которую я хочу проверить, находится в строке.

Может быть, это просто, но я не знаю как.

Редактировать: Спасибо за очень интересные ответы до сих пор. Я буду следовать вашим предложениям и интегрировать их в свой код, а также провести тестирование и составить отчет. Может занять некоторое время.

Edit2: Я еще раз взглянул на банку, и, может быть, лучше показать вам большую картину. Я благодарен экспертам за то, что они так красиво объясняются, лучше с большим количеством кода:

MYNAMESPACE.Loader = ( function() {

  function C() {
    this.modules = {};
    this.required = {};
    this.waitCount = 0;
    this.appendUrl = '';
    this.docHead = document.getElementsByTagName('head')[0];
  }

  function insert() {
    var that = this;
    //insert all script tags to the head now!
    //loop over all modules:
    for (var modName in this.required) {
      if(this.required.hasOwnProperty(modName)){
        if (this.required[modName] === 'required') {
          this.required[modName] = 'loading';
          this.waitCount = this.waitCount + 1;
          this.insertModule(modName);
        }
      }
    }

    //now poll until everything is loaded or 
    //until timout

    this.intervalId = 0;

    var checkFunction = function() {
      if (that.waitCount === 0) {
        clearInterval(that.intervalId);
        that.onSuccess();
        return;
      }
      for (var modName in that.required) {
        if(that.required.hasOwnProperty(modName)){
          if (that.required[modName] === 'loading') {
            var typeOfString = eval("typeof " + that.modules[modName].varName);
            if (typeOfString !== "undefined") {
              //module is loaded!
              that.required[modName] = 'ok';
              that.waitCount = that.waitCount - 1; 
              if (that.waitCount === 0) {
                clearInterval(that.intervalId);
                that.onSuccess();
                return;
              }
            }
          }
        }
      }
    };

    //execute the function twice a second to check if all is loaded:
    this.intervalId = setInterval(checkFunction, 500);
    //further execution will be in checkFunction,
    //so nothing left to do here
  }
  C.prototype.insert = insert;

  //there are more functions here...

  return C;
}());


var myLoader = new MYNAMESPACE.Loader();

//some more lines here... 

myLoader.insert();

Edit3:

Я планирую поместить это в глобальное пространство имен в переменную MYNAMESPACE.loadCheck, для простоты, так что результат будет, объединяясь из разных ответов и комментариев:

if (MYNAMESPACE.loadCheck.modules[modName].varName in window) {
  doSomething();
}

Конечно, мне придется обновлять класс Loader там, где когда-либо упоминается "varName".

Ответы [ 2 ]

3 голосов
/ 08 апреля 2010

в JS каждая переменная является свойством, если вы не знаете, чье это свойство, это свойство window, поэтому, я полагаю, в вашем случае это может сработать:

var typeOFString = typeof window[that.modules[modName].varName]
if (typeOFString !== "undefined") {
  doSomething();
}
1 голос
/ 08 апреля 2010

Поскольку вы проверяете только наличие предмета, вы можете использовать in вместо typeof.

Таким образом, для глобальных переменных согласно ответу ZJR вы можете искать их в объекте window:

if (that.modules[modName].varName in window) {
    ...
}

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

...