Reputation: 9382
Lets define a dog:
function Dog() {}
Now lets define a self executing function that passes the Dog as a parameter:
(function(dogClassName) {
var someServerSideLogicResolvesClassName = "dogClassName";
//Iniate class name from the server side string
})(Dog);
After some googleing I found that I should use
new window["dogClassName"]();
or
new this["dogClassName"]();
But since it's a scoped variable it doesn't exist in the global name space (no window) and this
is undefined
; I have no idea how to achieve this without using some sort of evaling.
Upvotes: 1
Views: 72
Reputation: 76433
Right, assuming that you're trying to access a constructor that isn't set globally, then the answer to your question is, quite simply: you can't do this. The scopes of closures are managed differently by the various engines. V8 might even GC the constructor if the returned function doesn't reference it explicitly...
There is no magic way to get a full outer scope as an object
The only solution would be to create a namespace-object:
(function()
{
var constructors = {Constructor1: function(){},
Constructor2: function(){}};
return function()
{
var className =getClassNameViaAjax();
if (constructors.hasOwnProperty(className))
{
return new constructors[className]();
}
if (window[className] instanceof Function)
{//fallback
return new window[className]()
}
throw className + ' Does not exist in closure, nor in global scope';
};
}());
Have a look at this question, it seems to me to be related, or even a duplicate.
Hesitant update, but for completeness
There is one way you can use a variable's value as reference in the scope chain, but it does require the most Evil of Evil functions: eval('new '+ className + '()')
, as you can see in the specification, eval will preserve the this
bindings, and reinitialize the scope chains. Except when you're using 'strict mode';
Since you're getting the constructor name from an ajax response, and eval
is an easy thing to exploit, don't do this! This is a sort of an "in theory, you could..." thing.
Upvotes: 2