0

I have a few strings

strings = [
    "String",
    "Object",
    "Boolean"
]

and I would like to use them to declare new objects

for(var i = 0; i < strings.length; i++){
    var x = new strings[i];
}

but instead I get this error:

TypeError: string is not a function
  at Object.<anonymous> (/Users/path/code.js)
  at Object.<anonymous> (/Users/path/code.js)
  at Module._compile (module.js:456:26)

How can I treat strings as their underlying types?


Aside:

I know that I could do something like

type_map = {
    String: String,
    Object: Object,
    Boolean: Boolean
}

and then go

for(var i = 0; i < strings.length; i++){
    var x = new type_map[strings[i]];
}

which works, but I'm looking for something slightly more elegant if it exists.

Loourr
  • 4,995
  • 10
  • 44
  • 68
  • `"String"` is a literal, you cannot instantiate a literal. – BatScream Nov 25 '14 at 23:24
  • Right, Perhaps I'm not phrasing this correctly, but what I'm trying to find out if there is some way to get the literal from the String string – Loourr Nov 25 '14 at 23:25
  • possible duplicate of [Create object from string](http://stackoverflow.com/questions/9803947/create-object-from-string) – TheDude Nov 25 '14 at 23:27
  • "new" can be used only on function, not on string. All global variables are elements of "window", so window["String"] corresponds to global function String. – Ivan Kuckir Nov 25 '14 at 23:48

3 Answers3

3

What's wrong with the obvious?

var i, x, constructors = [
    String,
    Object,
    Boolean
];

for(i = 0; i < constructors.length; i++){
    x = new constructors[i];
}

Bear in mind that anything in JS is an object (including "class names") and may be used, pretty much, however you want.

Alin Purcaru
  • 43,655
  • 12
  • 77
  • 90
1

The constructors for these classes are properties of the global object.

For example, in a browser, you could do

console.log(window['String'] === String); // true
var str = new window[strings[0]]();
console.log(str); // ""
guest
  • 6,450
  • 30
  • 44
0

Found a great way to do it with the eval function

strings = [
    "String",
    "Object",
    "Boolean"
]

for(var i = 0; i < strings.length; i++){
    var x = new (eval(strings[i]));
}

so to summarize eval("String") === [Function: String]

Loourr
  • 4,995
  • 10
  • 44
  • 68
  • Actually I think you found the one *wrong* way to do it. Please consider the other options before going to the `eval`, as you will spoil yourself with bad pratices. – Alin Purcaru Nov 25 '14 at 23:34
  • @BatScream Yeah, there's technically no problem. The eval will evaluate just the string and return the function contained in the object with the name specified by the string. Then will apply the function as a constructor on the context created by `new`. – Alin Purcaru Nov 25 '14 at 23:35
  • 1
    @AlinPurcaru -Thanks for the explanation. Got a clear picture. There is a syntax error there though i think. `new (eval(strings[i]))` – BatScream Nov 25 '14 at 23:50
  • 2
    Much better to use Alin's solution than using `eval()` as `eval()` is slow and generally something to shy away from unless there is no other solution, but usually, there is another solution. – jfriend00 Nov 26 '14 at 00:00
  • @BatScream It seems so. The new operator is implemented a bit differently than I imagined, but the error can be circumvented with some custom operator priorities: `new (eval(strings[i]))`. Disclaimer: This comment is just for sport, please don't use this code in software development. – Alin Purcaru Nov 26 '14 at 00:02