3

How to write this JavaScript code without eval?

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

The point is that the name of the var that I want to check for is in a string.

Maybe it is simple but I don't know how.

Edit: Thank you for the very interesting answers so far. I will follow your suggestions and integrate this into my code and do some testing and report. Could take a while.

Edit2: I had another look at the could and maybe itis better I show you a bigger picture. I am greatful for the experts to explain so beautiful, it is better with more code:

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:

I am planning to put this in the global namespace in variable MYNAMESPACE.loadCheck, for simplicity, so the result would be, combining from the different answers and comments:

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

Of course I will have to update the Loader class where ever "varName" is mentioned.

5
  • What is the problem with just doing typeof that.modules[modName].varName ? Can you post your whole code. Commented Apr 8, 2010 at 14:06
  • @Alexandre: it is code from a function of a loader class. So "that" refers to an instance of the class. The code is within a function of the class. Commented Apr 8, 2010 at 14:38
  • @Ivo: This is a whole class, I feel it's not adequate to post all the code. Sorry, I did not take the time to really reduce the code to just isolate the problem. But some posters seem to give solutions already. To answer your first questions: it is not a problem. I just wonder how to do it. I will report later and also paste more code then. Commented Apr 8, 2010 at 14:41
  • So you have a loader class and you want to check if some global variables have been imported by the loaded scripts. modName is the name of your module (loaded script) and varName is the name of the global variable that the script creates in the global object (window). Commented Apr 8, 2010 at 14:46
  • In the meantime I posted more code. There is class Loader with a function that has a callback function (using intervals) and it is in the callback function. Commented Apr 8, 2010 at 14:56

2 Answers 2

3

in JS every variable is a property, if you have no idea whose property it is, it's a window property, so I suppose, in your case, this could work:

var typeOFString = typeof window[that.modules[modName].varName]
if (typeOFString !== "undefined") {
  doSomething();
}
Sign up to request clarification or add additional context in comments.

6 Comments

otherwise (that is, if you're using the javascript with(object) {...} or you're in a function scope) you're supposed to search all the objects that could contain it, in sequence.
fyi you could use "this" rather than "window"
javascript function variables, IIRC, are function properties, so if you're doing: function x() {var a=10;} you will have to check for varName='a'; typeof x[varName];
this makes no sense here, if we're talking about variables and not properties of arbitrary objects. It would still work for plain function calls where this===window, but why would you do that?
Only global variables are properties of the global object. In other contexts, variables are not properties.
|
1

Since you are only testing for the existence of the item, you can use in rather than typeof.

So for global variables as per ZJR's answer, you can look for them on the window object:

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

If you need to look for local variables there's no way to do that without eval. But this would be a sign of a serious misdesign further up the line.

2 Comments

It's not exactly the same test. If the variable was declared but its value was undefined, then typeof would return "undefined", but in window would return true.
@Alsciende I can see the difference. In the case of this class it would not matter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.