smulz
smulz

Reputation: 47

Dynamically calling constructor from IIFE

Consider the following:

function windowTest() { }

(function () {
    function test() { }

    var test1 = new test(); // Works fine.
    var test2 = new window["windowTest"](); // Works since windowsTest is declared globally.
    var test3 = new window["test"]();  // Fails since in an IIFE.

    // How can I create a testObj if I only have the string "test"?
})();

Basically, I want to create an object whose function was declared in an IIFE.

Upvotes: 0

Views: 106

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138307

You can bind your functions to this:

function(){
 //your code using
 this.test("Hi");
 this["test"]("Hi");
}.call({
 //function declarations:
 test:window.alert,
});

Still an IIFE so it wont work in the global context :

this.test("Hi");//reference Error

Upvotes: 1

Mike Cluck
Mike Cluck

Reputation: 32511

The reason

var test3 = new window["test"]();

fails is because test was not declared globally. If you want to access items declared directly within the IIFE, as you know, you can access them by name.

new test();

Another way is to store your function inside of some kind of object then access that object like you did with window. This is almost always the solution to these kinds of problems.

(function() {
  var context = {
    test: function() {
      console.log('new test');
    }
  };
  
  var test = new context['test']();
})();

The last way uses eval. eval is almost always a really bad idea. Really, it should be avoided unless you're abusing the language just for the sake of interest. But you can use it in this case.

(function() {
  function test() {
    console.log('new test');
  }
  
  var test = eval('new test()');
})();

Upvotes: 2

Related Questions