84 votes

Comment créer un objet JavaScript en utilisant une variable String pour définir le nom de la classe ?

Voici ce que j'essaie de faire - c'est du pseudo-code et ça ne marche pas. Quelqu'un sait-il comment réaliser cela 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();

72voto

peirix Points 10728

Est-ce que ça marcherait si vous faisiez quelque chose comme ça :

var myObject = window[classNameString];

.. ?

0 votes

Ça a marché. Peirix, tu es génial. Tu penses que c'est compatible avec tous les navigateurs ?

1 votes

Je pense que tu voulais dire window[classNameString] (sans guillemets). Pause dès que MyClass est déplacé vers un niveau inférieur (c'est-à-dire que function ) scope. @kirk : oui, c'est un système multi-navigateur.

1 votes

Comment passer des arguments au constructeur en utilisant cette méthode ?

58voto

Yuriy Nemtsov Points 1430

Voici une solution plus robuste qui fonctionnera avec les fonctions à espacement 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();

0 votes

Pourquoi (windows || this) la fenêtre ne sera-t-elle pas toujours définie ?

12 votes

@JamesMcMahon : Le monde tel que nous le connaissons n'est plus la réalité. Des locataires comme nodejs sont aussi venus occuper notre planète ! :)

0 votes

Depuis l'arrivée du mode strict ( ECMA-262 ed 5 en 2009), window || this peut revenir indéfini dans un environnement non-browser si este n'est pas défini par l'appel (ce qui n'est pas le cas dans l'exemple).

35voto

bucabay Points 2511

BTW : window est la référence à l'objet global dans le navigateur JavaScript. Qui est aussi this et devrait fonctionner même dans des environnements autres que les navigateurs, tels que Node.js, les extensions Chrome, le code transposé, etc.

var obj = new this[classNameString]();

La limitation est que la classe appelée doit être dans le contexte global. Si vous voulez appliquer la même chose à une classe scopée, vous devez le faire :

var obj = (Function('return new ' + classNameString))()

Cependant, il n'y a pas vraiment de raison d'utiliser une chaîne de caractères. Les fonctions JavaScript sont elles-mêmes des objets, tout comme les chaînes de caractères qui sont également des objets.

Modifier

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]

De : Comment obtenir l'objet global en JavaScript ?

10 votes

C'est seulement this si elle est appelée depuis un contexte global. window fonctionne quel que soit le contexte dans lequel vous vous trouvez, je ne vois donc aucune raison de préférer this sur window .

6 votes

Comme l'indique la réponse, l'environnement dans lequel vous vous trouvez n'est pas nécessairement un navigateur. Par conséquent, l'utilisation de this est préférable, parce que dans un environnement sans navigateur window peut être indéfini, ou ne pas correspondre à ce que vous attendez.

0 votes

@XedinUnknown Habituellement, lorsque vous écrivez un morceau de javascript, vous savez s'il est destiné à un client ou, disons, à un nœud. Si vous savez que c'est pour un navigateur, alors il n'y a pas d'inconvénients à préférer window sur this .

14voto

Chetan Sastry Points 14742

Si MyClass est global, vous pouvez y accéder en tant que propriété de l'objet fenêtre (en supposant que votre code s'exécute dans un navigateur) en utilisant la notation de l'indice.

var myObject = new window["MyClass"]();

0 votes

Cela fonctionne-t-il dans tous les navigateurs ? Je vois des messages qui se plaignent que cela ne fonctionne pas pour eux.

3voto

pjesi Points 1286

Voici une version améliorée de la méthode de Yuriy qui traite é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;
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X