Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Créer un type JavaScript à partir de son nom : Type.createInstance

Je me suis retrouvé tout à l'heure à devoir créer un type JavaScript en ayant seulement son nom et les arguments du constructor. Voici la signature de la fonction que je devais alors coder.

Type.createInstance = function(typeName, args){ /// <summary> /// Create an objet of the specified type with the specified arguments. /// </summary> /// <param name="typeName" type="String">Name of the type to create.</param> /// <param name="args" type="Array">Arguments of the constructor.</param> /// <return type="Object">Returns the specified instance of the object.</return> }

Comment faire ? Réfléchissons à notre besoin : créer une instance d'un objet en ne connaissant que son nom et un tableau de paramètre. J'ai pensé à la méthode eval qui exécute du code sous sa forme littéral, il m'aurait alors suffit de créer un string contenant le code à exécuter. Cette solution me satisfaisait pas parce que les arguments ne sont pas tous de type simple, il m'aurait fallut serialiser les arguments. Et puis je n'aime pas eval qui souvent ralenti le code.

J'ai donc pensé à la méthode apply de l'objet Function, celle-ci permet d'appeler une fonction d'un autre objet avec un tableau de paramètre, j'avais déjà parlé de cette méthode avec sa cousine call ici : JavaScript : un langage incompris - Appel de fonctions. Après quelques essais voici le résultat.

Type.createInstance = function(typeName, args){ /// <summary> /// Create an objet of the specified type with the specified arguments. /// </summary> /// <param name="typeName" type="String">Name of the type to create.</param> /// <param name="args" type="Array">Arguments of the constructor.</param> /// <return type="Object">Returns the specified instance of the object.</return> var propType = Type.parse(typeName); var newType = function(){}; newType.prototype = propType.prototype; var obj = new newType(); propType.prototype.constructor.apply(obj, args); return obj; }

Tout d'abord je récupère le type de l'objet grâce à la méthode Type.parse du framework client Microsoft Ajax. Ensuite je déclare un nouveau type vide, je définis le prototype de ce type de façon à ce qu'il corresponde au prototype du type à créer. Puis je créer une instance du type vide. Cet instance possède le prototype recherché, techniquement c'est une instance de l'objet typeName mais sans que son constructeur ait été appelé, il me reste alors a appelé le constructor du type recherché sur mon objet. Cela se fait en utilisant la méthode apply sur la fonction constructor du prototype du type recherché.

Après analyse de mon code je me suis posé une question : que se passe t'il en mémoire ? est-ce que le prototype est partagé par les deux types ? ou alors est-il copié ? J'ai effectué quelques tests et le prototype est bien partagé entre mes deux types ! En utilisant cette méthode seul le constructeur type vide est conservé en mémoire c'est à dire une fonction vide donc pas grand chose.

J'avais trouvé une autre solution que je donne à titre informatif. Je ne vous conseil pas de l'utiliser puisqu'il peut y avoir des problèmes de "thread". En effet cette solution modifie le constructeur du type le temps de la création de l'instance de mon objet. Si ailleurs dans le code, un autre "thread" créer une instance de ce type celui ci ne sera pas appelé et cela peut vite causer des problèmes ...

var propType = Type.parse(typeName); var constructor = propType.prototype.constructor; propType.prototype.constructor = function(){}; var obj = new propType(); propType.prototype.constructor = constructor; return obj;

Je ne suis pas sur d'avoir été bien clair sur l'explication du code, si vous voulez en savoir plus, les commentaires sont là pour ça :-)

Posted: samedi 13 janvier 2007 22:09 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

FREMYCOMPANY a dit :

Moi ca me semble assez clair.

Mais ca risque de caller si tu teste ton objet via instanceof, non ?

# janvier 14, 2007 13:15

cyril a dit :

J'ai testé mais j'en ai pas parlé pour ne pas complexifier mon poste.

debug.trace(obj instanceof Itelios.Geo.Point); me retourne true :-) et Object.getTypeName(obj) me renvoie bien Itelios.Geo.Point. Donc tout est bon :-)

# janvier 14, 2007 13:35

Zorglub a dit :

function monType(a,b,c){this.b=b}

var inst=new window['monType'](1,2,3)

alert(inst.b) // 2

ca marche aussi ;)

# avril 15, 2007 06:28

cyril a dit :

Zorglub : As tu bien lu mon post ?

La question est comment créer une instance d'un type en ayant les arguments dans un tableau !

var args = [1,2,3]

var inst = new window[typeName](args)

ne fonctionne pas !

et puis déclaré des objets directement dans l'objet window c'est pas ce qu'il y a de plus propre ...

# avril 15, 2007 12:51

Zorglub a dit :

&gt; Zorglub : As tu bien lu mon post ?

&gt; La question est comment créer une instance d'un type

&gt; en ayant les arguments dans un tableau !

^^' ... j'ai principalement lu le titre... en fait :]

"Créer un type JavaScript *à partir de son nom*"

(nan mais c'est ça aussi de de poster à 6h du mat... ^^)

bon j'ai regardé plus sérieusement et c'est vrai que c'est bien trouvé Cyril :)

J'ai essayé de le refaire autrement, sans grand succès.

je propose une légère variante en closure qui offre l'avantage de renvoyer un constructor (ca peut etre pratique pour le stocker et l'appeler directement pour les autres instances).

function createInstance(typeName, args){

 return new (createConstructor(typeName,args))

}

function createConstructor(typeName, args){

 var propType = window[typeName] // ou Type.parse(typeName) si MicrosoftAjax actif

 function f(){propType.apply(this,args)}

 f.prototype=propType.prototype

 return f

}

// Test:

function monType(a,b,c){// Pas vraiment un type MSAjax, mais c'est pour la demo

 this.a=a

 this.c=c

 this.toString=function(){

   return this.a+' '+this.b+' '+this.c

 }

}

monType.prototype.b=2

var o=createInstance('monType',[1,0,3])

var a=createInstance('monType',[1,0,3])

alert(o instanceof monType) // true

o.constructor.prototype.b=-2

o.b=2

alert(o) // 1 2 3

alert(a instanceof monType)

alert(a) // 1 -2 3

# avril 16, 2007 08:45

Zorglub a dit :

petite correction dans f()

la bonne fonction est :

function f(){propType.apply(this,args||arguments)}

cela permet d'utiliser

var o=createInstance('monType',[1,0,3])

ou

var C=createConstructor('monType'),

   o=new C(1,0,3)

(ce dernier cas n'est pas tellement utile pour le problème posé ici)

# avril 16, 2007 09:13
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01

- SharePoint Online: Script PowerShell pour supprimer une colonne dans tous les sites d’une collection par Blog Technique de Romelard Fabrice le 11-27-2018, 18:01