admin管理员组文章数量:1134247
Here's what I'm trying to do -- this is pseudo code and doesn't work. Does anyone know how to accomplish this for real:
// Define the class
MyClass = Class.extend({});
// Store the class name in a string
var classNameString = 'MyClass';
// Instantiate the object using the class name string
var myObject = new classNameString();
Here's what I'm trying to do -- this is pseudo code and doesn't work. Does anyone know how to accomplish this for real:
// Define the class
MyClass = Class.extend({});
// Store the class name in a string
var classNameString = 'MyClass';
// Instantiate the object using the class name string
var myObject = new classNameString();
Share
Improve this question
edited Oct 12, 2018 at 11:00
mikemaccana
123k110 gold badges425 silver badges529 bronze badges
asked Sep 2, 2009 at 6:34
Kirk OuimetKirk Ouimet
28.3k44 gold badges130 silver badges182 bronze badges
12 Answers
Reset to default 75Would it work if you did something like this:
var myObject = window[classNameString];
..?
Here's a more robust solution that will work with namespaced functions:
var stringToFunction = function(str) {
var arr = str.split(".");
var fn = (window || this);
for (var i = 0, len = arr.length; i < len; i++) {
fn = fn[arr[i]];
}
if (typeof fn !== "function") {
throw new Error("function not found");
}
return fn;
};
Example:
my = {};
my.namespaced = {};
(my.namespaced.MyClass = function() {
console.log("constructed");
}).prototype = {
do: function() {
console.log("doing");
}
};
var MyClass = stringToFunction("my.namespaced.MyClass");
var instance = new MyClass();
instance.do();
BTW: window is the reference to the global Object in browser JavaScript. Which is also this
, and should work even in non-browser environments such as Node.js, Chrome extensions, transpiled code etc.
var obj = new this[classNameString]();
The limitation is that the class being called must be in the global context. If you want to apply the same to a scoped class you need to do:
var obj = (Function('return new ' + classNameString))()
However, there really is no reason to use a string. JavaScript functions are themselves objects, just like strings which are objects also.
Edit
Here is a better way to get the global scope that works in strict mode as well as non-browser JS environments:
var global;
try {
global = Function('return this')() || (42, eval)('this');
} catch(e) {
global = window;
}
// and then
var obj = new global[classNameString]
From: How to get the global object in JavaScript?
If MyClass is global, you can access it as a property of window object (assuming your code runs in a browser) using subscript notation.
var myObject = new window["MyClass"]();
If classNameString
come from secure source you can use
var classNameString = 'MyClass';
var myObject = eval("new " + classNameString + "()");
This solution works with namespaces and is independent on platform (browser/server).
Browser global object is window
and whenever you define global variables with var
or functions with function
, you are adding them in window
.
Thus you can get your "class" definition there:
var args = [];
var className = 'MyClass';
var obj = new window[className](args);
But this won't work for ES6 class declarations
Classes declared using ES6 keyword class
are per-standard treated differently.
A class declared with class MyClass { }
defines a global class that does not become a property of window
global object. In other words the following applies
class MyClass {};
typeof window.MyClass === 'undefined';
So, how to do the same with ES6 classes? Object access notation is required because is what is needed to parse the string name, but parent object to search in is no longer available.
One way is to create your own context object, declare there your class and search for it there. In code:
// this variable actually goes in `window`
var classes = {};
// declare class inside
classes.MyClass = class {
// the class code
};
var args = [];
var className = 'MyClass';
var obj = new classes[className](args); // dynamic for "new classes.MyClass(args)"
function myClass(arg){
}
var str="myClass";
dynamic_class=eval(str);
var instance=new dynamic_class(arg); // OK
Edit: inline example
function Person(name){
this.name=name;
}
var person1=new (eval("Person"))("joe");
This works:
import { Class1 } from './profiles/class1.js'
import { Class2 } from './profiles/class2.js'
let profiles = {
Class1,
Class2
}
let profileAsString = 'Class1'
new profiles[profileAsString]()
Here is improved version of Yuriy's method that also handles objects.
var stringToObject = function(str, type) {
type = type || "object"; // can pass "function"
var arr = str.split(".");
var fn = (window || this);
for (var i = 0, len = arr.length; i < len; i++) {
fn = fn[arr[i]];
}
if (typeof fn !== type) {
throw new Error(type +" not found: " + str);
}
return fn;
};
In my case I was preloading data from my server and attempting to load the preloaded data using classes (in particular, I am using vuex-orm). Instead of anything super fancy, I opted for a list of models that I expect, and mapped them to classes that I had already imported at the top of the file. Observe:
import Video from '@models/Video'
import Purchase from '@models/Purchase'
let modelClassMap = {
'Video': Video,
'Purchase': Purchase,
}
Object.entries(preload.models).forEach(entry => {
const [modelName, modelData] = entry
if(modelClassMap[modelName]){
modelClassMap[modelName].insertOrUpdate({data: modelData})
}
})
Explicit, secure, simple. Nice!
myOption = {.......}
new (eval( varNameClass ))({ param0:'xxx', myThis: this, option: myOption })
On Firefox, there are security rules for extensions, and so for the Javascript console. Don't make the mistake I did to test in the console because none of those solutions work. Whereas when you test from a page it works better :
- the eval solution works well
- Function('return new '... works (object is created) except for the constructor's arguments that are passed as "undefined" I didn't test other solutions.
本文标签: oopHow do I make JavaScript Object using a variable String to define the class nameStack Overflow
版权声明:本文标题:oop - How do I make JavaScript Object using a variable String to define the class name? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736811126a1953898.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论