Voici ce que j'essaie de faire - c'est du pseudo-code et cela ne fonctionne pas. Quelqu'un sait-il comment y parvenir pour de vrai:
// 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();
Cela fonctionnerait-il si vous faisiez quelque chose comme ceci:
var myObject = window[classNameString];
..?
Voici une solution plus robuste qui fonctionnera avec des fonctions à espace de noms:
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;
};
Exemple:
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 est la référence à l'objet global dans le navigateur JavaScript. Qui est également this
, et devrait fonctionner même dans des environnements sans navigateur tels que Node.js, Chrome, code transpilé, etc.
var obj = new this[classNameString]();
La limitation est que la classe appelée doit être dans le contexte global. Si vous souhaitez appliquer la même chose à une classe de portée, vous devez faire:
var obj = (Function('return new ' + classNameString))()
Cependant, il n'y a vraiment aucune raison d'utiliser une chaîne. Les fonctions JavaScript sont elles-mêmes des objets, tout comme les chaînes qui sont également des objets.
Voici une meilleure façon d'obtenir la portée globale qui fonctionne en mode strict ainsi que dans les environnements JS sans navigateur:
var global;
try {
global = Function('return this')() || (42, eval)('this');
} catch(e) {
global = window;
}
// and then
var obj = new global[classNameString]
Si MyClass est global, vous pouvez y accéder en tant que propriété d'un objet window (en supposant que votre code s'exécute dans un navigateur) en utilisant la notation en indice.
var myObject = new window["MyClass"]();
Si classNameString
provient d'une source sécurisée, vous pouvez utiliser
var classNameString = 'MyClass';
var myObject = eval("new " + classNameString + "()");
Cette solution fonctionne avec des espaces de noms et est indépendante de la plateforme (navigateur/serveur).
Voici une version améliorée de la méthode de Yuriy qui gère également les objets.
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;
};