IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Débat : Vos bonnes pratiques JavaScript

Le , par Community Management

0PARTAGES

3  0 
Bonjour,

De par sa nature, JavaScript est plutôt mal loti concernant les bonnes pratiques de code.
L'apparition du "Web 2.0" a entrainé un regain d'intérêt pour ce langage, ainsi qu'une évolution notable de celui-ci.
Cependant, encore trop de codes obsolètes trainent sur la toile, codes souvent réalisés pour des versions anciennes des principaux navigateurs.
De plus, la syntaxe JavaScript est particulièrement permissive.
Tout cela implique que de trop nombreux débutants, se contentant de copier/coller des codes sans les comprendre, de même que par la suite, des développeurs confirmés continuent à utiliser des mauvais codes par habitude.

Je vous propose donc dans cette discussion d'indiquer ce que vous considérez comme la meilleure syntaxe JavaScript, que ce soit en terme de fonctions et méthodes à privilégier ou proscrire ou simplement en terme d'écriture du code.

A terme, le but est de collecter ces bonnes et mauvaises pratiques dans un article.

Nous vous demandons toutefois de respecter quelques règles élémentaires :
  • Ceci est un débat

Cela implique que des avis parfois contradictoires sont susceptibles d'apparaitre.
Il est donc impératif de rester courtois et de ne pas troller inutilement
Gardez à l'esprit qu'il faut savoir rester humble et que le fait d'avoir un avis ne fait pas de celui-ci une vérité absolue !
  • Pour chaque intervention

Donner son point de vue est une chose, l'expliquer et l'argumenter est encore mieux, merci donc d'expliquer au mieux les raisons de votre (vos) choix, cela permettra à la discussion d'être constructive et pédagogique.
  • Faites attention à ceux qui vous liront !

Il est important de bien rédiger ses interventions.
Certes, nous ne demandons pas que vous soyez dignes de l'académie française, mais prenez le temps de vous relire, de corriger vos fautes.
Le langage SMS, comme sur l'ensemble des forums est interdit.

Tout message ne respectant pas ces règles sera susceptible d'être supprimé à vue

à tous ceux qui participeront à cette discussion.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Watilin
Expert éminent https://www.developpez.com
Le 08/02/2013 à 18:51
Lcf, je pense que tu en as déjà entendu parler, mais je le dis au cas où : il existe en JavaScript une directive "use strict";. John Resig, le créateur de jQuery, a écrit un billet dessus

Personnellement, je préfère déclarer mes fonctions avec function plutôt que var car je sais que de toute façon elles seront dans le scope local. Ça fait, à mon goût, un code plus lisible pour le même résultat. Ensuite, je leur donne toujours un nom, après le mot-clé function, car comme vous l'avez dit, ce nom apparaît dans la pile lors du débogage.

Ce qui se passe est plutôt simple : le débogueur utilise la propriété name qu'ont toutes les fonctions. Quand la fonction a été déclarée sans nom, sa propriété name est une chaîne vide "".

Code console : Sélectionner tout
1
2
3
4
5
6
7
8
>>> var x = function fun( ){} 
undefined 
>>> x.name 
"fun" 
>>> var y = function( ){} 
undefined 
>>> y.name 
""

Pour changer de sujet, j'ai découvert il y a pas plus de 3 jours l'outil JSLint, qui est une sorte de « relecteur » JavaScript, à défaut d'être un correcteur. Il met en évidence certaines erreurs et mauvaises pratiques.
J'ai aussi découvert que Douglas Crockford a écrit des conventions de codage pour JavaScript. Cela dit, j'ai adopté les miennes et je les aime bien et, après tout, ce n'est pas très différent
3  0 
Avatar de Auteur
Expert éminent sénior https://www.developpez.com
Le 13/03/2011 à 13:11
Arrêter de croire que la réponse à un problème simple passe nécessairement par l'utilisation d'une bibliothèque....

Ce n'est pas une critique envers les diverses bibliothèques javascript qui existent actuellement, mais je vois de plus en plus dans la résolution de problèmes simples des réponses du genre "utilise la bibliothèque unetelle ou une autre" alors que souvent 10 lignes de code suffisent à résoudre le problème.

Edit :
tiens je me répète
2  0 
Avatar de Auteur
Expert éminent sénior https://www.developpez.com
Le 17/05/2009 à 11:56
Pour commencer :
  • Toujours déclarer ses variables qu'elles soient locales ou globales :
    Firefox est très sensible à ça et avec IE on peut avoir de mauvaises surprises ;
  • le nom de variables ne doit pas être un mot-clef JS ou l'id ou le name d'un élément ou le nom d'une balise (cf. le lien ci-dessus) ;
  • bannir innerHTML pour inclure dans la page des nouveaux éléments (div, input, table, etc.). Utiliser le DOM ;
  • bannir document.write()
  • dans les balises HTML écrire le nom des événements en minuscules (sinon ça ne passe pas la validation W3C) ;


Ensuite en ce qui me concerne, j'évite les méthodes getAttribute() et setAttribute(). Au lieu d'utiliser setAttribute(), je préfère écrire :
element.style.attribut = "valeur";
au moins tous les navigateurs reconnaissent cette syntaxe.

J'évite également addEventListener() et attachEvent() (les navigateurs reconnaissent soit l'une soit l'autre fonction), je préfère cette écriture :
element.onevent = function(){mafonction()};
1  0 
Avatar de franculo_caoulene
Membre émérite https://www.developpez.com
Le 19/05/2009 à 12:14
9 == '9' retourne true
9 === '9' retourne false
1  0 
Avatar de Willpower
Membre expérimenté https://www.developpez.com
Le 12/03/2011 à 22:07
Citation Envoyé par laurentg2003 Voir le message
tout a fait d'accord avec les différents posts
sauf pour une chose
plutôt que if(mavar== "undefined"
je prefere if(undefined==mavar)
c'est une proriété js et donc pas de string et donc un gain de performance et en cas d'erreur de syntaxe genre (mavar="undefined"
le script généra une erreur direct
Ca dépendra de la nature de l'objet à tester je dirai.

Dans bien des cas,
Code : Sélectionner tout
if(obj=="undefined")
renverra "false" même si l'objet est undefined (il faudrait faire : if(typeof obj=="undefined" pour obtenir un "true", il est donc évident qu'il vaut mieux utiliser la propriété undefined plutot qu'un string.

par contre si on sait d'avance que la nature de notre obj devrait être de type "Object object" par exemple(enfin, n'importe quoi sauf un booleen et un entier qui pourraient valoir 0 ou false), il est plus simple (et plus rapide*) de tester
Code : Sélectionner tout
if(!obj)
.

*plus rapide, d'après mes testes, de :
~2% sous ff
~35% sous chrome
~65% sous ie

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function compare(fn1,fn2){
	var MAX_DELAY = 20,
	NBR_TEST = 9;
	//
	var tab1=[],tab2=[],iter=1,delay=0,median=Math.round(NBR_TEST /2),time;
	while(delay<MAX_DELAY){
                time=new Date().getTime();
		for(var j=(iter*=2);j>0;j--){
			fn1();
			fn2();
		}
		delay = (new Date().getTime())-time;
	}
	for(;NBR_TEST>0;NBR_TEST--){
		// test fn1
		time = new Date().getTime();
		for(var j=iter;j>0;j--)
			fn1();
		tab1.push((new Date().getTime())-time);
		// test fn2
		time = new Date().getTime();
		for(var j=iter;j>0;j--)
			fn2();
		tab2.push((new Date().getTime())-time);
	}
	tab1.sort(function(a,b){return a-b;});
	tab2.sort(function(a,b){return a-b;});
	return (tab1[median]/tab2[median]);
}
//	test1
	function f1(u){
		for(var i=0;i<1 && !u;i++);
	}
	function f2(u){
		for(var i=0;i<1 && u==undefined;i++);
	}
	alert("ration (!u)/(u==undefined) : "+Math.round(compare(f1,f2)*100)+"% (1/ration  = "+Math.round(compare(f2,f1)*100)+"%)");
	
//	test2		
	function f11(u){
		for(var i=0;i<10000 && !u;i++);
	}
	function f22(u){
		for(var i=0;i<10000 && u==undefined;i++);
	}
	alert("ration (!u)/(u==undefined) : "+Math.round(compare(f11,f22)*100)+"% (1/ration = "+Math.round(compare(f22,f11)*100)+"%)");
1  0 
Avatar de sekaijin
Expert éminent https://www.developpez.com
Le 13/03/2011 à 18:15
Citation Envoyé par Auteur Voir le message
Arrêter de croire que la réponse à un problème simple passe nécessairement par l'utilisation d'une bibliothèque....

Ce n'est pas une critique envers les diverses bibliothèques javascript qui existent actuellement, mais je vois de plus en plus dans la résolution de problèmes simples des réponses du genre "utilise la bibliothèque unetelle ou une autre" alors que souvent 10 lignes de code suffisent à résoudre le problème.

Edit :
tiens je me répète
C'est sur qu'il vaut mieux 10 ligne de code.
Et à l'opposé arrêter de penser que vous ferrez mieux que des dizaines de developpeurs
et évitez de réécrire ce que d'autres ont fait dans des librairies de façon efficace et éprouvé.

donc en toutes circonstances soyez pragmatique.

A+JYT
1  0 
Avatar de sekaijin
Expert éminent https://www.developpez.com
Le 15/03/2011 à 10:25
Pourquoi à chaque fois on ne se concentre que sur une partie du post des gens
en omettant ce qui change tout son sens ?

donc en toutes circonstances soyez pragmatique.
C'est étonnant de voir que lorsque quelqu'un dit
il a A
ou il a B

Les réaction sont
il a A
et ceci mais cela

Heu les gars un post c'est un tout
Lisez le entier. et si vous en critiquez une partie n'oubliez de citer ce qui dans le reste dit exactement la même chose que votre critique.

A+JYT
1  0 
Avatar de sekaijin
Expert éminent https://www.developpez.com
Le 15/03/2011 à 17:09
Citation Envoyé par laurentg2003  Voir le message
A madevilts
pourquoi eviter les getElementById();??

parce que ça consomme du temps et ça ne sert à rien la plus part du temps

exemple on cherche l''élément à chaque click
Code html : Sélectionner tout
1
2
3
4
5
<script>myFonction(id) { 
   el = document.getElementById(id); 
   //fait quelque chose avec el 
}</script>  
<a id="45" onclick="return myFonction(45)">click</a>
le même
Code html : Sélectionner tout
1
2
3
4
<script>myFonction(el) { 
   //fait quelque chose avec el 
}</script>  
<a onclick="return myFonction(this)">click</a>

sur un objet autre que lui-même
Code html : Sélectionner tout
1
2
3
4
5
6
7
8
<div id="45">.... 
<script> 
//on ne recherche q'une fois 
els[45] = document.getElementById(45); 
myFonction(id) { 
   //fait quelque chose avec el[45] 
}</script>  
<a onclick="return myFonction(45)">click</a>
là où je ne suis pas entièrement d'accord avec madevilts
c'est qu'en utilisant le dom tu te passe de toutes les recherches
Code : Sélectionner tout
1
2
3
4
5
6
7
div45 = document.createElement('DIV'); 
... 
a = document.createElement('A'); 
a.ref=div45; 
a.onclick = function () { 
  //fait quelque chose avec this.ref 
}
c'est surtout jouable lorsque tu par d'un HML vide et que tu construit ton appli entièrement en js. là tu a intérêt à garder les référence au objet que tu manipuleras de façon évènementielle pour ne pas avoir à les chercher tout le temps.

lorsque tu fait un site en HTML et que tu ne fais que y ajouter un peu de js
getElementById est parfait. mais pourquoi l'appeler à chaque événement si tu peux le faire une seule fois.

je pense à un script que j'ai vu récemment qui sur un timer toute les seconde va chercher un div et lui remplacer son contenu par l'heure courante.
alors que placer la référence au div dans une variable une première fois puis sur le timer utiliser la référence est bien plus efficace.

A+JYT
1  0 
Avatar de
https://www.developpez.com
Le 11/07/2011 à 16:52
Pour ma part, en plus de ce qui a déjà été dit :
  • Préférer au possible le passage d'objet en paramètres de fonction lorsque beaucoup d'arguments.
    Code : Sélectionner tout
    1
    2
    3
    4
    function toto(obj){
     /*ie : obj=={name:'bob',firstName:'moran',...}; */
    }
  • Une seule "classe"=function à instancier avec new par fichier et nommer son fichier du même nom que la fonction avec la première lettre en majuscule.
    Cela facilite l'exploration du code quand on dev.
  • Les fonctions ne nécessitant pas instanciation ont justement la première lettre en minuscule.
  • Toujours des accollades {} autour des if/else. Ca a déjà été dit, mais je rajoute une raison (que j'ai pe ratée). Il s'agit de pouvoir facilement tracer le code en rajoutant une ligne dans le bloc (console.log par exemple). Donc c'est pas perdu.
  • Lors de la définition d'une fermeture, préférer la première syntaxe
    Code : Sélectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function Popper(objParams){
      var _private = objParams['specialProperty'];
      var that = {};
      that.kikoo = function(){
       return _private;
      };
      that.kikooUpper = function(){
        return that.kikoo().toUpperCase();
      };
      return that;
    }
    à la suivante
    Code : Sélectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function Popper(objParams){
      var _private = objParams['specialProperty'];
      var kikoo = function(){
        return _private;
      }
      return {
        kikoo:kikoo,
        kikooUpper:function(){
          return kikoo().toUpperCase();
        }
      };
    }
    Dans le premier cas, on a déjà moins d'indentation.
    En plus, les méthodes définies sur that sont déjà accessibles par celles qu'on définit par la suite.
    Dans la seconde, on est obligé de définir kikoo pour pouvoir l'appeler depuis kikooUpper, donc autant définir directement sur la variable that.
  • Egalement, préfixer les variables "privées" (non visibles par l'appelant) par un underscore.
  • Et un anti-pattern : on ne peut pas utiliser un nom de variable qui est un mot clé du langage. Donc par exemple
    Code : Sélectionner tout
    1
    2
    3
    4
    function popper(class){
     //do some stuff on html nodes with 'class' attr
    }
    est incorrect.
    J'ai déjà vu du
    Code : Sélectionner tout
    1
    2
    3
    4
    function popper(klass){
     //do some stuff on html nodes with 'class' attr
    }
    pour contourner le probleme. C'est mauvais car pertube l'esprit. Préférer className, ou quelquechose dans le genre.


Voilà pour ma part.
1  0 
Avatar de sekaijin
Expert éminent https://www.developpez.com
Le 04/02/2012 à 18:28
Bonjour pourquoi utiliser un texte là ou une référence fonctionne

Code : Sélectionner tout
window.setTimeout(function () {alert("toto")}, 300)
ou
Code : Sélectionner tout
1
2
toto = function () {alert("toto")}; 
window.setTimeout(toto, 300)
la dernière version compressée donne la même chose ou avec obfuscator
Code : Sélectionner tout
eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('0=1(){2("0")};3.4(0,5);',6,6,'toto|function|alert|window|setTimeout|300'.split('|'),0,{}))
ce qui fonctionne toujours très bien.

de façon générale mieux vaut utiliser une référence qu'un texte qui interprété donnera un appel à la référence.

par exemple ne pas faire
Code : Sélectionner tout
function toto() {alert("toto")};
Code html : Sélectionner tout
<a id='truc' onClick='toto()'>...
qui sera évalué pour créer dynamiquement une fonction qui sera placé comme membre de l'élément truc
le navigateur va générer ceci:
Code : Sélectionner tout
1
2
function toto() {alert("toto")}; 
document.getElementById('truc').onclick= function() {toto();};
mais
Code : Sélectionner tout
document.getElementById('truc').onclick=function() {alert("toto")};
ou encore
Code : Sélectionner tout
1
2
function toto() {alert("toto")}; 
document.getElementById('truc').onclick=toto;
en conclusion pensez aux références
A+JYT
1  0