Folgendes versuche ich zu tun - dies ist Pseudocode und funktioniert nicht. Weiß jemand, wie man das wirklich erreicht:
// 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();
javascript
oop
Kirk Ouimet
quelle
quelle
window[classNameString]
(keine Anführungszeichen). Bricht ab, sobaldMyClass
ein niedrigerer (dhfunction
) Bereich erreicht wird. @ Kirk: Ja, das ist Cross-Browser.window[classNameString](args)
. Aber wie Crescent Fresh erwähnt, seien Sie vorsichtig, da dies in einigen Fällen brechen kann.var obj = new Home(id);
aber das funktioniert nicht :var obj = new window["Home"](id);
. Ich versuche, dies zumnew window[x](id);
x = "Home"
Uncaught TypeError: window[x] is not a constructor
Hier ist eine robustere Lösung, die mit Funktionen mit Namespace funktioniert:
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; };
Beispiel:
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();
quelle
(windows || this)
wird das Fenster nicht immer definiert?window || this
kann er in einer Umgebung ohne Browser undefiniert zurückgegeben werden, wenn dies nicht durch den Aufruf festgelegt wurde (was im Beispiel nicht der Fall ist).Übrigens: Fenster ist der Verweis auf das globale Objekt in Browser-JavaScript. Das ist auch
this
und sollte auch in Nicht-Browser-Umgebungen wie Node.js, Chrome-Erweiterungen, transpiliertem Code usw. funktionieren.var obj = new this[classNameString]();
Die Einschränkung besteht darin, dass sich die aufgerufene Klasse im globalen Kontext befinden muss. Wenn Sie dasselbe auf eine Klasse mit Gültigkeitsbereich anwenden möchten, müssen Sie Folgendes tun:
var obj = (Function('return new ' + classNameString))()
Es gibt jedoch wirklich keinen Grund, eine Zeichenfolge zu verwenden. JavaScript-Funktionen sind selbst Objekte, genau wie Zeichenfolgen, die auch Objekte sind.
Bearbeiten
Hier ist ein besserer Weg, um den globalen Bereich zu erhalten, der sowohl im strengen Modus als auch in JS-Umgebungen ohne Browser funktioniert:
var global; try { global = Function('return this')() || (42, eval)('this'); } catch(e) { global = window; } // and then var obj = new global[classNameString]
Von: Wie erhalte ich das globale Objekt in JavaScript?
quelle
this
wenn aus einem globalen Kontext aufgerufen.window
arbeitet unabhängig vom Kontext Sie sind, so dass ich keinen Grund zu bevorzugen sehenthis
überwindow
.this
vorzuziehen, da in einer Umgebung ohne Browserwindow
möglicherweise nicht definiert ist oder nicht den Erwartungen entspricht.window
überthis
.this
, nicht istwindow
. Darüber hinaus ist der zuverlässigste Weg, den globalen Kontext NICHT aus dem globalen Kontext heraus zu referenzieren, dertop
. Vielleicht auch gut, um es in den Verschluss zu injizieren.Function('return this')()
stattreturn this
. Ersteres wechselt automatisch in den globalen Kontext. Dies funktioniert unabhängig vom Kontext. Fenster kann überschrieben werden und ist nur Browser. Es ist gut, den Kontext der Codeausführung nicht zu kennen, um plattformübergreifenden Code zu schreiben. Die Antwort, die ich gegeben habe, ist plattformübergreifend und kann nicht überschrieben werden und ist daher viel besser als die Verwendungwindow
. Es funktioniert in transpiliertem Code, wie mit Webpack, Gulp und in Knoten, Erweiterungen usw. Bitte testen Sie es zuerst.Wenn MyClass global ist, können Sie als Eigenschaft eines Fensterobjekts (vorausgesetzt, Ihr Code wird in einem Browser ausgeführt) unter Verwendung der tiefgestellten Notation darauf zugreifen.
var myObject = new window["MyClass"]();
quelle
Wenn Sie
classNameString
aus einer sicheren Quelle stammen, können Sie diese verwendenvar classNameString = 'MyClass'; var myObject = eval("new " + classNameString + "()");
Diese Lösung funktioniert mit Namespaces und ist plattformunabhängig (Browser / Server).
quelle
eval
Wenn Sie gehört haben, dass es eine schlechte Idee ist, ist das wie betrunken zu fahren. "Nichts ist passiert ... hic ... das letzte Mal, als ich Alkohol gefahren bin ... hic ... tatsächlich fahre ich besser betrunken! ... hic ..." Bis etwas schief geht, ist es zu spät. Sei nicht dieser Typ.Hier ist eine verbesserte Version von Yuriys Methode, die auch Objekte behandelt.
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; };
quelle
function myClass(arg){ } var str="myClass"; dynamic_class=eval(str); var instance=new dynamic_class(arg); // OK
quelle
In Firefox gibt es Sicherheitsregeln für Erweiterungen und damit für die Javascript-Konsole. Machen Sie nicht den Fehler, den ich beim Testen in der Konsole gemacht habe, da keine dieser Lösungen funktioniert. Wenn Sie von einer Seite aus testen, funktioniert dies besser:
Auf Französisch: Sur Firefox il ya des règles de sécurité qui s'appliquent aux extensions und donc à la console Javascript. Ne faites pas l'erreur que j'ai faite de tester depuis la console car aucune de ces solutions ne marchent. Par contre quand on teste depuis une page cela fonctionne mieux:
quelle