5

I searched the web for some way to create instance of "Class" in "reflection" using javaScript but I found nothing.

generally i'm trying to do someting like java code.

Object o = Class.forename("MyClassName");

but in javaScript, in such way that I'll get the instance of class when I have only the name of the class, any idea?

Thankes.

4 Answers 4

7

JavaScript doesn't have classes. But if by "class" you mean you have a constructor function:

function MyClassName() {
   // do constructor things here
}

But the name of that function is in a variable:

var someclass = "MyClassName";

Then you can instantiate an instance like this:

var obj = new window[someclass]();

The above only works if MyClassName is in the global scope.

Sign up to request clarification or add additional context in comments.

4 Comments

firefox: TypeError: window[className] is not a constructor
chrome: Uncaught TypeError: window[className] is not a constructor
edge:Object doesn't support this action
@user648026 - I just tried this in Chrome and it worked fine. Are you sure you defined the function in the global scope as mentioned in the answer? Either way, note that this answer is from nearly eight years ago, so...
0

Classes in Javascript are nothing but global functions. So you should be able to do this:

var o = new window["MyClassName"];

for example:

var o = new window["Array"];

Keep in mind that this example is just an example. Arrays should be created via [] syntax.

Comments

0

This is working for me:

var obj = eval("new  " + className + "()");

1 Comment

until classname is Array(); runMaliciousCode();//
0

Now that JavaScript has classes thought I would offer an updated solution.

ES6 introduced an API that makes this extremely trivial but supports all new things JavaScript (modules for example, which weren't addressed in other answers, and doesn't worry about 'window' scope as mentioned in other comments). The Reflect API is well supported across browsers and all the methods are static and aren't limited to just classes, it works with objects in general.

The Reflect API even has convenience methods that are helpful beyond 'reflection-like' implementation. For example, you can quickly determine if an object has a key with:

console.log(Reflect.has(target, <key>))

Which can be considered an alternate of:

console.log(obj[<key>] !== undefined)

To instantiate a new instance of a class via javascript reflection you can call the Reflect.construct(<target>, arugmentsList) method:

animal.js

export default class Animal {

   constructor(type) {
      this.type = type;
   }

   get canSwim() {
      return ['amphibians', 'fish'].includes(this.type);
   }

}

main.js

import Animal from "./animal.js"

const instance = Reflect.construct(Animal, ['bird']);
console.log(Reflect.get(instance, 'canSwim')) //returns false

Just for brevity, you can still use mutators and accessors per normal, I simply used the Reflection.get() method for this example to demonstrate it exists, but the following is synonymous:

const instance = Reflect.construct(Animal, ['bird']);
console.log(instance.canSwim) //returns false

Of course, this works without modules, this example just demonstrates it with modules.

Reference:

7 Comments

You should use the Reflect object only for implementing proxy traps. To access properties, use instance.canSwim, to check for properties, use Object.hasOwn(object, 'key') or 'key' in obj, and to construct instances, use new Animal('bird').
Sure @Bergi . Like I said, it was a crude example just to demonstrate what methods it has. I agree, if you know the concrete class obviously call it directly but if you are using a factory class or some sort of utility class where the class is given as an argument and you don’t know the concrete class this is good alternative
No! new works with arbitrary/dynamic classes just as well: function construct(C) { return new C; }
@Bergi I’m not trying to be difficult but I truly don’t understand your point. Yes, if you know the concrete class obviously call it per normal conventions. No one is googling “how to instantiate a known concrete class with reflection” … especially via JavaScript. There are circumstances where you don’t know the concrete class and need to instantiate it. Clearly there is a need for it or else the entire Reflect API wouldn’t even exist. I just used my examples for readability but I didn’t think I would need to disclaim that on a question about meta programming strategies like reflection
Accessing a class by name from the current scope is a different issue, that's what eval and window[name] get at. This is nothing that Reflect helps with anyway ("[The Reflect API] supports all new things JavaScript (modules for example …)" is flat out wrong, Reflect has nothing to do with modules). But once you have a reference to the class, you can replace any Reflect.construct(<target>, arugmentsList) call with new <target>(...arugmentsList) and it works exactly the same. No need for Reflect, you should not use it here - but your answer suggests otherwise.
|

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.