Bienvenue sur PEBKAC.fr, le site qui recense les anecdotes où l’on se moque des utilisateurs ne maîtrisant pas l’outil informatique. PEBKAC est un acronyme signifiant « Problem Exists Between Keyboard And Chair ».
Le problème se situe entre la chaise et le clavier : soumettez vos histoires, donnez votre avis !
Ce site n'est pas le site original pebkac.fr. Je publie ici la liste des PEBKAC que j'ai pu sauvegarder avant que le site original ne soit mis hors ligne.
Aujourd'hui, maintenant du code pour un site à fort trafic, j'ai découvert une perle Javascript dans un plan de tag.

var champTags = [,,,,,,,,,,];

champTags[0] = '1'; //v
champTags[1] = document.getElementById("mail").value;
champTags[2] = 'SomeData';
champTags[3] = '';//num com
champTags[4] = document.getElementById("telephone").value;
champTags[5] = ''; //migra
champTags[6] = ''; //rio
champTags[7] = $("input[name=civilite]:checked").next("span").text();
champTags[8] = document.getElementById("nom").value;
champTags[9] = document.getElementById("prenom").value;

var string = "something/" + champTags[0] + '/' + champTags[1] + '/' + champTags[2] + '/' + champTags[3] + '/' + champTags[4] + '/' + champTags[5] + '/' + champTags[6] + '/' + champTags[7] + '/' + champTags[8] + '/' + champTags[9] + ';'

En plus d'allouer à l'avance des clés sur un array pour les remplir juste après, l'auteur de cette perle ne semble manifestement pas connaître le fort utile Array.prototype.join();. PEBKAC.
PEBKAC #9653 proposé par Yimi le 19/03/2014 | 26 commentaires | 👍🏽 👎🏽 +42
Je n'ose imaginer s'il avait dû joindre 100 champs. J'espère au moins qu'il a fait un c/c sinon ça fait cher l'heure de dactylo.
Commentaire #134544 écrit par H. Finch le 19/03/2014 à 08h49 | 👍🏽 👎🏽
En plus d'allouer à l'avance des clés sur un array pour les remplir juste après...

C'est inutile en JS ? Je travaille de temps à autre sous Matlab, et la pré-allocation lors de la déclaration permet d'optimiser le fonctionnement et l'attribution d'espace mémoire.
Commentaire #134546 écrit par Link le 19/03/2014 à 08h55 | 👍🏽 👎🏽
Pareil en Lua, la seule façon d'allouer de l'espace dans un tableau (plutôt que de provoquer des allocations au remplissage) est d'utiliser une liste d'initialisation un peu comme ici.

Du coup si le JS se comporte de la même façon, CTLP pour ce point-là
Commentaire #134550 écrit par Lynix le 19/03/2014 à 09h00 | 👍🏽 👎🏽
Aucun avis sur la question (je ne connais pas javascript), j'attendrai de lire plus de commentaires avant de voter.
Commentaire #134551 écrit par Raizarachi le 19/03/2014 à 09h00 | 👍🏽 👎🏽
Il y a deux trucs qui me paraissent bizarres (en plus de ce qui est souligné par l'auteur):
- L'alternance Javascript / jQuery
$("input[name=civilite]:checked").next("span").text();
- Il y a quoi dans ce span ? oO
Commentaire #134554 écrit par Kelgarath le 19/03/2014 à 09h15 | 👍🏽 👎🏽
En js, ce n'est pas nécessaire de preallouer un tableau, qui peut être rempli au fur et a mesure.
Après, selon le navigateur et l'implémentation de la machine js il peut être possible que la preallocation pour les petit tableau soit plus efficace. Mais c'est marginal.
Mais si l'optimisation etait importante, il aurait utilisé array.push, qui peut etre plus rapide que l'allocation par index.
Donc petit petit pebkac la dessus.

En revanche, le mélange de vanilla js (document.getelementbyid ...) et de jquery ($(machin).next ...), si on est extrême ça pourrait friser le pebkac.

L'absence de join en revanche, c'est vraiment con. D'autant plus que ça peut être plus rapide que la concaténation de chaines de caractères.

Bref, un pebkac, mais un petit.
Commentaire #134557 écrit par whiteshoulders le 19/03/2014 à 09h24 | 👍🏽 👎🏽
C'est surtout que dans ces cas là je ne vois pas bien l'utilité de passer par un array plutôt que par des variables indépendantes avec des noms qui parlent ! A part peut être pour retourner dans la déclaration de l'array voir à quoi correspond chaque entrée histoire de bien perdre du temps...

 var id = '1'; //v
 var mail = document.getElementById("mail").value;
 var data = 'SomeData';
 var com = '';//num com
 var phone = document.getElementById("telephone").value;
 var migra = ''; //migra
 var rio = ''; //rio
 var isChecked = $("input[name=civilite]:checked").next("span").text();
 var name = document.getElementById("nom").value;
 var firstName = document.getElementById("prenom").value;
 
 var string = "something/" + id + '/' + mail + '/' + data + '/' + com + '/' + phone + '/' + migra + '/' + rio + '/' + isChecked + '/' + name + '/' + firstname + ';'
 


Après si il ne s'en sert pas plus loin (mais c'est moins lisible) :
 var string = "something/" + '1' + '/' + document.getElementById("mail").value + '/' + 'SomeData' + '/' + '' + '/' + document.getElementById("telephone").value + '/' + '' + '/' + '' + '/' + $("input[name=civilite]:checked").next("span").text() + '/' + document.getElementById("nom").value + '/' + document.getElementById("prenom").value + ';'
 


Mais bon c'est sûr que :
 var champTags = [,,,,,,,,,,];
 
 champTags[0] = '1'; //v
 champTags[1] = document.getElementById("mail").value;
 champTags[2] = 'SomeData';
 champTags[3] = '';//num com
 champTags[4] = document.getElementById("telephone").value;
 champTags[5] = ''; //migra
 champTags[6] = ''; //rio
 champTags[7] = $("input[name=civilite]:checked").next("span").text();
 champTags[8] = document.getElementById("nom").value;
 champTags[9] = document.getElementById("prenom").value;
 
 var string = champTags.join('/')
 

C'est bien aussi ^^
Commentaire #134558 écrit par Shadam le 19/03/2014 à 09h28 | 👍🏽 👎🏽
v a r SPC s t r i n g SPC = SPC " s o m e t h i n g / "F3 SPC + SPC c h a m p T a g s [ F3 ] SPC + SPC ' / ' F4 C-u 9 F4 C-b C-b C-d ; C-e

:p
Commentaire #134559 écrit par Macro le 19/03/2014 à 09h37 | 👍🏽 👎🏽
Il doit y avoir le texte correspondant à la civilité cochée (Monsieur, Madame, Mademoiselle), rien de bizarre là dedans
Commentaire #134561 écrit par LapinouDesCarpates le 19/03/2014 à 09h49 | 👍🏽 👎🏽
Texte qu'on peut bien plus facilement mettre dans la value du bouton radio qui est coché.
Commentaire #134562 écrit par Kelgarath le 19/03/2014 à 09h51 | 👍🏽 👎🏽
J'allais demander l'aide de quelqu'un pour une invocation de Captain Obvious. Tu veux m'aider ? =)

De ce que je comprends, il remplis "manuellement" chaque champ en allant le séléctionner "en dur" avant d'affichier un "résumé" du tableau sous forme "Something/<Entrée1>/<Entrée2>/<Entrée3>/[...]"

Après, j'suis nul en Dev, donc je "ne vois pas" de PEBKAC ici.... Mais je le sens vu qu'il y a surement carrément plus simple et plus optimisé en 2 ligne plutôt qu'en cent.
Commentaire #134563 écrit par Fox le 19/03/2014 à 09h56 | 👍🏽 👎🏽
Il ne te manque pas le "something" en début de chaîne avec le .join('/') ?
Commentaire #134565 écrit par Acorah le 19/03/2014 à 09h59 | 👍🏽 👎🏽
var string  = "something/" + 
         	'1/' + //v
         	document.getElementById("mail").value + '/' + 
         	'SomeData' + '/' + 
         	'/' + //num com
         	document.getElementById("telephone").value + '/' + 
         	'/' + //migra
         	'/' +  //rio
         	$("input[name=civilite]:checked").next("span").text() + '/' + 
         	document.getElementById("nom").value + '/' + 
         	document.getElementById("prenom").value + ';';


Fais la même chose, évite d'utiliser un tableau, et reste tout aussi lisible...

Après faut voir si le tableau est réutilisé à un autre endroit, ça peut alors se justifier.

Si on parle de performance, sur les navigateurs récents, aucune différence, sur les plus anciens comme IE6, l'utilisation de concaténation successives avec le + est extrêmement lent, et utiliser un tableau peut alors se justifier.... si on utilise join !

Donc ouais, un petit PEBKAC quand même, pourquoi faire simple quand on peut faire compliqué ?

PS : ah oui, et comme dit ailleurs, l'alternance JS/jQuery et aller chercher la valeur d'un input dans un span adjacent plutôt que dans son attribut value, ça tient aussi du PEBKAC.
Commentaire #134569 écrit par Quadehar le 19/03/2014 à 10h16 | 👍🏽 👎🏽
Anéfé : var string = 'something/' + champTags.join('/')
Commentaire #134573 écrit par Shadam le 19/03/2014 à 10h29 | 👍🏽 👎🏽
D'accord avec Shadam plus haut, si le mec ne se ressert pas de son array plus loin, dans ce cas autant tout concaténer directement dans une chaîne (en indentant un peu on peut avoir quelque chose de très propre).

Après en restant purement sur la solution proposée, déjà pourquoi s'emmerder avec les clefs alors qu'on peut faire simplement :
champTags = [
                        '1', //v
                        document.getElementById("mail").value,
                        'SomeData',
                        '',//num com
                        document.getElementById("telephone").value
                        // [etc...]
                       ]


Ou encore
champTags = [];
 champTags.push('1'); // to be continued....


Et puis surtout ne pas connaître la méthode join() n'est pas le PEBKAC car même sans join() on peut tout de même faire un truc propre avec une boucle, au lieu de tout se taper à la main :

var string = "something";
 for (var i = 0; i<champTags.length;i++) {
     string += '/' + champTags[i];
 }


De toute façon j'imagine que la chaîne concaténée va être "explosée" à un moment ou un autre : en effet je ne vois vraiment pas à quoi peut servir ce genre de chose : something/mail@domain.fr/SomeData//0123456789///Mr/Truc/Muche... pour moi il ne peut s'agir que d'une sorte de sérialisation... Pourquoi ne pas passer par du JSON dans ce cas ?
Rien que de très utile dans ce bout de code !
Commentaire #134580 écrit par aDev le 19/03/2014 à 11h24 | 👍🏽 👎🏽
@Kelgarath, sauf erreur la value d'un bouton radio ne s'affiche pas, donc un span ou une autre balise est nécessaire pour afficher à l'écran Monsieur, Madame, Mademoiselle.
Et peut-être que la value est déjà utlisée avec dedans un id correspondant à la civilité en base.
Commentaire #134582 écrit par LapinouDesCarpates le 19/03/2014 à 11h41 | 👍🏽 👎🏽
Ce n'est pas parce que ça ne d'affiche pas que tu ne peux pas mettre de valeur dedans...

<input type="checkbox" name="cb_mister" value="Mister" >Mister
Commentaire #134594 écrit par Shadam le 19/03/2014 à 12h36 | 👍🏽 👎🏽
@Shadam, je sais, j'avais spécifié ci-dessus que la value était peut-être déjà utlisée par un id, donc la solution de Kelgarath n'est pas forcément une option réalisable.
Commentaire #134596 écrit par LapinouDesCarpates le 19/03/2014 à 12h48 | 👍🏽 👎🏽
Je n'ai pas dit qu'il était nécessaire de préallouer les tableaux Lua, juste que c'était plus efficace car on avait alors directement un tableau capable d'accueillir nos données, plutôt qu'un tableau qui va s'allouer automatiquement plusieurs fois avant d'atteindre au final la même taille.
Commentaire #134601 écrit par Lynix le 19/03/2014 à 13h25 | 👍🏽 👎🏽
Qu'est ce qui empêche de rajouter un attribut supplémentaire genre <code>data-value</code> contenant la valeur ?
Possible uniquement en HTML 5?
Commentaire #134615 écrit par Jypyx le 19/03/2014 à 16h18 | 👍🏽 👎🏽
@Jypyx, hormis les restrictions liées au doctype (html5) c'est plutôt une bonne idée je trouve
Commentaire #134616 écrit par LapinouDesCarpates le 19/03/2014 à 16h28 | 👍🏽 👎🏽
[ici insérer une blague salace avec le mot "array"]
Commentaire #134759 écrit par ROB le 20/03/2014 à 12h17 | 👍🏽 👎🏽
Oula ça se déchaîne, et vous avez même relevé d'autres perles en plus de celles sur lesquelles j'ai bloqué.

Pour répondre plus ou moins dans l'ordre:
- Non le tableau n'est pas réutilisé plus loin
- L'alternance jquery + natif viens du fait qu'il ne connais pas le classname
- En parlant de jquery, un $('form').serialize() lui aurait donné un résultat équivalent (oui vous n'avez pas le html mais je vous assure que c'était faisable).
- Pour le <span/>, au lieu de mettre un value sur une chechbox il allais chercher la valeur écrite dans le span a coté (span qui servais au passage de label).
- La personne qui à rédigé cette beauté à justifié son code pour de la minification sans utiliser de minifier (on cherche toujours l'explication entre nous) tout en ayant un code optimisé (ce qui n'est évidement pas le cas).
- Non ce n'est pas opti de pré allouer des clé dans un array en javascript (dans un objet c'est une autre histoire). Le push() est bien plus rapide.
- J'ai vu un commentaire sur les data-attributes, il les utilisent dans une autre partie du gros bloc de javascript d'ou est extrait ce tout petit bout.
- Monsieur tiens a son code, pas de json non ce serait trop simple.
- @aDev faire une boucle qui au final reproduit le fonctionnement d'une fonction native ce n'est pas vraiment malin.

Pour conclure, oui c'est de "petits" pebkacs pour quelqu'un qui débute, sauf qu'on a affaire a quelqu'un qui en fait depuis au moins 5 ans si ce n'est plus. Mais ceci n'est que une toute petite fraction d'un fichier de 400 lignes de code de qualité équivalente. Sur un fichier JS dont dépendent quasiment tous les services.
Commentaire #134916 écrit par Yimi le 20/03/2014 à 20h33 | 👍🏽 👎🏽
Je n'avais pas fait attention à la ligne de jQuery :-/

Perso je trouve que ça fait un peu le mec qui a trouvé ce bout de code car il ne voyait pas comment récupérer le radio button en vanilla (d'après ce que je vois il n'a pas l'air d'être un pro de jQuery).

Concernant faire une boucle qui au final reproduit le fonctionnement d'une fonction native ce n'est pas vraiment malin. je suis on ne peut plus d'accord, j'illustrais simplement le fait que ne pas connaître une fonction (en plus de ne pas vérifier si elle existe, ce qui est une autre histoire sur laquelle j'ai volontairement fait l'impasse) qui pourrait nous être utile n'est pas une excuse pour produire un code dégueulasse.
Commentaire #135025 écrit par aDev le 21/03/2014 à 17h12 | 👍🏽 👎🏽
Je vais peut-être pinailler mais :
1. le code est correct
2. le code est globalement aussi lisible que si on avait composé le tableau avec des join()
3. la perte d'optimisation est très peu perceptible dans la mesure où ce code est destiné à n'être exécuté qu'une fois par chargement de page (et côté client).

Donc, même si tu as raison sur le fond, et qu'il vaut mieux prendre de bonnes habitudes de programmation – un code reste parfois utilisé pendant un paquet d'années et parfois on le réutilise ailleurs – ça reste léger au final.
Commentaire #135052 écrit par /etc/passwd le 22/03/2014 à 10h32 | 👍🏽 👎🏽
Fonctionnel peut être, correct non.
Je veux bien qu'il ne faille pas optimiser à outrance, perte de temps de productivité et autre, mais la (et je me suis renseigné) on à affaire a quelqu'un qui apparemment fait du javascript depuis 15 ans. Du coup cette non utilisation de fonctions native peut laisser perplexe.
Et je me répète mais ces quelques lignes sont qu'un fragment d'un bien plus gros fichier, qui est lui bien moins lisible (en tous cas par des humains).
Commentaire #135114 écrit par Yimi le 23/03/2014 à 13h02 | 👍🏽 👎🏽