25

Is it possible to create a new object using a string? For example, how can I convert the string "product" to var p = new Product?

Thanks in advance.

EDIT

What I want to do is to have a menu with <a href="#home"></a><a href="#products">products</a> and create the corresponding object from the href each time.

Unheilig
  • 16,196
  • 193
  • 68
  • 98
chchrist
  • 18,854
  • 11
  • 48
  • 82
  • what do you hope to do with it? – Joseph Mar 21 '12 at 11:44
  • 1
    What's the rule to convert `product` to `var p = new Product`? I can understand `new Product`, but why `p`? – Felix Kling Mar 21 '12 at 11:44
  • @chchrist: That sounds dangerous, especially if the string comes from the user... why do you think that is this a good idea? Have you considered any alternative approaches? – Mark Byers Mar 21 '12 at 11:44
  • possible duplicate of [Instantiate a JavaScript Object Using a String to Define the Class Name](http://stackoverflow.com/questions/1366127/instantiate-a-javascript-object-using-a-string-to-define-the-class-name) – Scott Dudley Sep 23 '15 at 19:44

3 Answers3

75

If you know the context, yes. Let's say you're in a browser environment and Person is a global constructor. Because any global variable is a property of the global object, it means you can access to Person through the global object window:

var p = new Person()

Is equivalent to:

var p = new window.Person()

So you can use the square bracket notation:

var p = new window["Person"]();

Of course this is valid for every kind of object. If you don't want pollute the global scope, you can have:

var mynamespace = {};

mynamespace.Person = function Person() {..}

var p = new mynamespace["Person"]();
ZER0
  • 24,846
  • 5
  • 51
  • 54
  • 6
    That's a much nicer solution than mine +1 – Matt Fellows Mar 21 '12 at 11:57
  • I've tried to create an object using new window["Namespace.MyClass"](), but looks like it's not working. How can we create objects when class contains in modules? – Narendra V Jan 09 '14 at 15:50
  • @NarendraV try new window["Namespace"]["MyClass"]() ? (This is just a guess, I don't know that this will work) – Matt Fellows Jan 10 '14 at 11:53
  • @NarendraV, you can use the square bracket notation instead of dot notation, not both: you basically tried to get a property named "Namespace.MyClass" from window where what you were looking was get `Namespace` from window, and then from `Namespace`, `MyClass`. @MattFellows shown the proper way to do so. You can also create a function like: `function getReference(string, root) { root = root || this; return string.split(".").reduce(function(ref, item) { return ref[item] }, root) };`, and use as `var o = new getReference("Namespace.MyClass")()`. it's a very simple one, you can make it better. – ZER0 Jan 12 '14 at 10:47
7

Well you could always use the hideously insecure and illadvised eval(). e.g.

var myStr = "Product"
var p = eval("new " + myStr + "()");

or that might be:

var myStr = "Product"
eval("var p = new " + myStr + "()");

But it's fraught with potential vulnerabilities, especially if the string is coming from user input.

Matt Fellows
  • 6,512
  • 4
  • 35
  • 57
1

Just another implementation:

var nameOfThang = 'Person';
var nameOfThingzName = 'The Dude';

var thangs = { Person: {name: 'Legowski'}, Cars: {} };
var person  = new (eval(thangs[nameOfThang].constructor))();
person.name = new (eval(thangs.Person.name.constructor))(nameOfThingzName) .toString();

console.log('@thang, #Person', person);
Cody
  • 9,785
  • 4
  • 61
  • 46