|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Bonjour à tous.
Quelqu'un saurait-il m'expliquer pourquoi l'ajout de méthodes à un objet rends cette méthode visible lors de l'itération for ? Exemple: Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||
|
00
|
|
|
#2 | ||||
|
Membre régulier
![]() Inscription : décembre 2007 Messages : 61 ![]() |
Cela est du au mécanisme d'héritage en javascript. Lorqu'une propriété ne peut être résolue le runtime va chercher de manière récursive dans la chaine de prototypage.
De la même manière lors d'une itération sur les clés tu itère sur les clés de l'objet (instances) mais aussi sur les clés visibles dans ta chaine de prototypage. Pour itérer sur un objet sans itérer les clés héritées il faut faire : Code :
Code :
|
||||
|
|
10
|
|
|
#3 | ||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
Effectivement, c'est dangereux d'ajouter des prototypes à tous les Objets et jQuery a parfois un peu du mal avec ça.
essaye de faire des trucs du genre : Code :
|
||
|
|
10
|
|
|
#4 | |
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Merci @TheGwy. Ce que je ne comprenais pas c'est pourquoi les membre natifs des objets ne se retrouvent pas dans la liste des clés. Pourtant cela fait effectivement partie de leur prototype. Dois-je en déduire que c'est la VM qui "masque" ces clés ?
Citation:
)Vu qu'on ne devrait pas les augmenter, peut-on au moins en hériter ?
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|
|
00
|
|
|
#5 | |
![]() ![]() ![]() Didier MouronvalDéveloppeur Web Inscription : juin 2008 Messages : 13 807 ![]() |
Citation:
__________________
Pas de question technique par MP ! Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi ! Vous possédez un blog et aimeriez diffuser vos billets sur le forum, contactez-moi ! Mes formations video2brain : La formation complète sur JavaScript • JavaScript et le DOM par la pratique • PHP 5 et MySQL : les fondamentaux Mon livre sur jQuery
|
|
|
00
|
|
|
#6 | ||
|
Membre régulier
![]() Inscription : décembre 2007 Messages : 61 ![]() |
Citation:
https://developer.mozilla.org/en/ECM...Enum_attribute Les nouvelles API ES5 permettent d'avoir accès à cette propriété, mais d'ici la que ce soit utilisable partout, tu as le temps de venir voir. Citation:
Personnellement je suis plutôt adepte de l'objet avec des fonctions utilitaires statiques (genre StringUtils, etc). C'est un peu plus "lourd" syntaxiquement mais très clair niveau compréhension. Après si c'est un projet de petite ampleur où tu es l'auteur de tout le code (pas de passif, source externes, mashups, librairies, plugins) tu peux te permettre d'étendre les objets natifs car tu ne risque pas de casser du code qui n'est pas le tiens. Mais c'est quand même rare de se retrouver dans ce cas. Un bon article sur la question avec plusieurs approches décortiquées : http://perfectionkills.com/extending...s-evil-or-not/ |
||
|
|
00
|
|
|
#7 | |||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Citation:
J'ai tenté ça mais visiblement il manque quelque chose: Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|||
|
00
|
|
|
#8 |
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
le problème c'est qu'en javascript, il y a grosso-modo 2 types de variables, les objets et les valeurs.
le string étant ce j'appelle une variable de type valeur. tu ne pourras donc jamais faire de "write(myString)" en espérant afficher la valeur de ton String car ton "myString" sera un objet avec des champs et des méthodes. tu devras choisir soit à redéfinir toutes les méthodes de ton nouvelle objet "myString" du genre "myString.write()" soit rédéfinir le prototype de la classe String de base(native), ce qui est clairement mieux dans ce cas. en fait, pour les variables de type "valeur"(string, number, etc...) tu as intêret à jouer avec les prototypes. tandis que pour les objets, tu as intêret à créer une nouvelle classe encapsulante. (les array, étant un type d'objet particulier, c'est plus génant.). sinon comme le suggère theGwy, l'utilisation de fonctions utilitaires statiques sera encore le plus simple dans bien des cas. |
|
|
00
|
|
|
#9 |
|
Membre régulier
![]() Inscription : décembre 2007 Messages : 61 ![]() |
En fait c'est un peu plus vicieux que cela.
Il y a une subtilité en javascript les types littéraux peuvent avoir des méthodes car ils sont autoboxés. Quand tu fais par exemple "string".trim() le runtime va : - convertir ta string littérale en objet String, - executer String.trim - reconvertir l'objet en valeur littérale C'est visible parfois quand tu essaie d'attribuer une propriété à une valeur littérale : l'objet est autoboxé, ta propriété est écrite sans lever d'erreur, puis reconvertit en littéral ce qui te fait perdre ta propriété. Je pense que ton problème ici doit plus ou moins être en rapport avec ça (sous firebug ton code déclenche une récursion infinie). Mais en toute honnêteté je n'ai pas trop gratté. Si tu veux plus d'infos sur ce comportement tu devrais trouver ça sur le net, mais je sais (pour l'avoir lu) que "Javascript patterns" de stoyan stefanov consacre un chapitre la dessus où il explique tout de manière très claire. |
|
|
00
|
|
|
#10 | ||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
En effet, je viens de lire un article intéressant sur l'autoboxing de JavaScript (ça m'a rappelé les wrappeurs en Java).
Il semblerait donc que les objets natifs soient impossible à hériter en totalité car je n'arrive pas à redéfinir correctement .valueOf (on peut toujours passer par Object mais du coup, on ne réccupère jamais la chaine - on a [object Object]). Bref, j'ai finalement trouvé un moyen en utilisant une composition: Code :
Pour ceux que ça intéresse, voici le thread de Stack Overflow qui m'a mis sur la voie:http://stackoverflow.com/questions/6...ecially-string Edit: y'avait une erreur dans mon code.
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||
|
00
|
|
|
#11 |
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
Ca ne marche que pour la classe "string" car en fait il y a conversion implicite de type (je pense) en string et que tu as surchargé la méthode toString.
|
|
|
00
|
|
|
#12 | ||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Je pense également. Mais c'est pas moi l'expert ici
![]() Le problème n'a pas l'air de se poser pour d'autres type, c'est assez étrange je dois dire... Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||
|
00
|
|
|
#13 | ||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
pas bête l'utilisation de push pour convertir le this en array.
)autrement, pour le fun, j'ai supprimé ta boucle de création(même si au final le code native qui la substitue doit sans doute en faire une lui aussi). et j'ai rajouté la méthode toString car (en tout cas sous chrome) un alert(myArray) provoquait une exception disant que Array.prototype.toString n'était pas générique. Code :
|
||
|
|
10
|
|
|
#14 | ||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Bien joué, merci.
Apparement l'usage de Array.prototype.toString ne pose aucun problème dans le contexte de myArray: Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||
|
00
|
|
|
#15 | |||||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
quand j'utilise ton code sous chrome :
Code :
Code :
j'ai une exception : Citation:
edit: explications de ma version return this.slice().toString(); : en gros la méthode slice découpe un sous-array dans ton array à partir de la position arguments[0], sans argument ça découpe par défaut depuis la position 0, donc un sous-array commençant au début(jusqu'à la fin) donc ton array. (mais de type array et non myArray), donc myArrayObject.slice().toString(), renverra une conversion de myArray en array et appliquera le toString natif du array. |
|||||
|
|
00
|
|
|
#16 | ||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
en mode un peu barbare :
Code :
Code :
((myArray=function(){[].push.apply(this,arguments)}).prototype=[]).toString=function(){return this.slice()+''}; |
||
|
|
00
|
|
|
#17 |
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 991 ![]() |
Je vois... C'est étrange car les instances de myArray sont bien des Array (instanceof renvoie true). Donc je n'arrive pas à comprendre d'où vient cette erreur de "généricité"...
Qu'on soit bien d'accord, c'est pas quelque chose qui me gène de redéfinir toString sans même appeller la méthode de la classe mère. Je me pose juste la question; comment fonctionne l'héritage de types natifs en JS. J'ai encore deux-trois articles à lire sur la question, j'espère y trouver des réponses.
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|
00
|
|
|
#18 | |
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
Citation:
ton objet reste un objet de type myArray mais ne devient jamais réellement un objet de type array. même s'il "hérite" de ses méthodes via son prototypage et que "instanceof" renvoie vrai car la signature de l'array sera accesible depuis ton objet via le prototype qu'il a hérité. apparement la création de ton objet via la méthode "push" le rend encore un peu plus array en lui ajoutant par exemple un attribut length et fait que la majorité des méthodes héritées via le prototype d'array(slice, concat, etc..) acceptent de s'exécuter sur ton objet malgré qu'il ne soit pas réellement un array natif. par contre il n'arrive pas à appliquer la méthode toString(de array) sur ton objet qui de base est un "object object". d'ailleurs si dans ta méthode myArray.prototype.toString tu fais : return Object.prototype.toString.call(this); il ne renverra pas d'erreur. Mais ce ne sera pas le toString que tu attends car il affichera "[Object Object]" au lieu de par exemple "[1,2,3]". c'est pour quoi, dans ma méthode toString, je converti d'abord l'objet myArray en vrai array avant de lui appliquer le toString d'array. de même, tu aurais intêret à tester toutes les méthodes du prototype d'array car il en existe p-ê d'autres qui refusent de s'appliquer sur ton objet qui n'est pas réellement un array. enfin, je ne suis pas expert, mais il me semble que mes explications sont les bonnes. |
|
|
|
00
|
|
|
#19 | ||||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
après des rapides test sur un objet de type myArray. toutes les méthodes semblent bien fonctionner.
il y a juste l'attribut "constructor" qui fait référence à Array au lieu de myArray. tu peux le corriger comme ceci : Code :
myArray.prototype.constructor = myArray; // à placer après la surcharge du prototype par le new Array(); enfin, la méthode concat, qui renvoie un array et non un myArray. exemple : Code :
objectMyArray.concat(objectMyArray); // renvoie un nouvel array et non un myArray Code :
il suffirait alors de faire (pour concat) un truc du genre : Code :
|
||||
|
|
00
|
|
|
#20 | ||||
|
Membre Expert
![]() Boris Dessysans emploi Inscription : décembre 2010 Messages : 871 ![]() |
en résumé, complété et commenté :
Code :
exemple d'utilisation : Code :
|
||||
|
|
10
|
Copyright © 2000-2012 - www.developpez.com