Quel que soit notre niveau actuel, nous étions tous débutants à un moment donné. Faire des erreurs classiques de débutant vient avec le territoire. Aujourd'hui, nous avons demandé à plusieurs auteurs du personnel de Nettuts + de préciser leur liste de pièges et de solutions, dans différentes langues..
Apprendre de nos erreurs; ne fais pas ces choses!
Le DOM est lent. Limiter votre interaction avec celui-ci augmentera considérablement les performances de votre code. Considérez le code (mauvais) suivant:
// anti-motif pour (var i = 0; i < 100; i++) var li = $("
Ce code effectivement modifie le DOM 100 fois et crée inutilement 100 objets jQuery. 100! Une approche plus correcte consisterait à utiliser un fragment de document ou à créer une chaîne contenant le caractère 100 éléments, puis ajoute ce code HTML à l'élément qui le contient. De cette façon, vous sautez une fois dans le DOM. Voici un exemple:
var liststring = ""; pour (var i = 100; i> 0; i -) liststring + = "
Comme indiqué ci-dessus, avec cette technique, nous ne touchons le DOM qu'une seule fois, ce qui constitue une amélioration, mais elle repose également sur la concaténation de chaînes pour créer une chaîne de grande taille. Il y a une autre façon d'aborder cela, en utilisant des tableaux.
var liststring = "
Lors de la construction de grandes chaînes, stocker chaque partie de la chaîne en tant qu’élément dans un élément de tableau et appeler joindre()
est sans doute plus élégant que la concaténation de chaînes. C’est l’un des moyens les plus rapides et les plus simples de créer du code HTML répétitif en JavaScript sans utiliser de bibliothèque de modèles ni de framework.
Cet élément suivant n'est pas un problème de performances, mais est extrêmement important, en particulier si vous travaillez sur du code sur lequel d'autres personnes travaillent également. Gardez vos identifiants (noms de variables et de fonctions) cohérents. Considérez les variables suivantes comme exemple:
var foo = "bar"; var plant = "green"; var car = "rouge";
Il ne serait pas logique d'ajouter une autre variable, appelée Quelque chose
. Cela introduit une incohérence dans votre modèle de dénomination des variables, ce qui amène votre cerveau à marquer cognitivement cette variable comme étant différente ou spéciale. C’est pourquoi les constantes dans la plupart des langues sont traditionnellement définies avec des majuscules..
Vous pouvez aller plus loin en maintenant une longueur, une structure grammaticale et une nature explicative similaires lors de la désignation des fonctions. Par exemple, considérons la fonction artificielle suivante:
fonction subtractFive (nombre) nombre retourné - 5;
Nommer une fonction qui ajoute cinq à un nombre donné devrait suivre le même schéma, présenté ici:
fonction addFive (numéro) numéro de retour + 5;
Parfois, vous pouvez nommer une fonction pour indiquer sa valeur de retour. Par exemple, vous pouvez nommer une fonction qui retourne une chaîne HTML getTweetHTML ()
. Vous pouvez également ajouter le nom d'une fonction avec faire
, si la fonction effectue simplement une opération et ne renvoie pas de valeur, par exemple: doFetchTweets ()
.
Les fonctions de constructeur suivent généralement la tradition des classes dans d'autres langues, en capitalisant la première lettre:
function Chien (couleur) this.color = color;
En règle générale, vous devez décrire vos identifiants de manière descriptive. Classez-les avec d'autres identificateurs similaires en conservant un modèle de dénomination lisible qui donne des indications sur la nature de la variable ou de la fonction..
hasOwnProperty ()
dans pour… dans
BouclesLes tableaux de JavaScript ne sont pas associatifs. essayer de les utiliser comme tels est mal vu par la communauté. Les objets, d’autre part, peuvent être traités comme des tables de hachage et vous pouvez parcourir les propriétés d’un objet à l’aide de la touche pour… dans
boucle, comme si:
for (var prop dans unObjet) alert (unObjet [prop]); // valeur d'alerte de la propriété
Le problème, cependant, est que le pour… dans
loop itère sur chaque propriété énumérable de la chaîne de prototypes de l'objet. Cela peut être problématique si vous souhaitez uniquement utiliser les propriétés existantes sur l'objet réel..
Vous pouvez résoudre ce problème en utilisant le hasOwnProperty ()
méthode. Voici un exemple:
for (var prop dans someObject) if (someObject.hasOwnProperty (prop)) alert (someObject [prop]); // valeur d'alerte de la propriété
Cette version alerte uniquement les valeurs des propriétés qui résident directement sur un objet
.
La comparaison de valeurs booléennes dans une condition est une perte de temps de calcul. Jetez un oeil à ce qui suit pour un exemple:
if (foo == true) // faire quelque chose pour vrai else // faire quelque chose pour faux
Remarquez la condition: toto == vrai
. La comparaison de foo
et vrai
est inutile car foo
est déjà une valeur booléenne (ou c'est une vérité ou une falsey). Au lieu de comparer foo
, utilisez-le simplement comme condition, comme ceci:
if (foo) // faire quelque chose pour vrai else // faire quelque chose pour faux
Pour tester faux
, utilisez l'opérateur logique NOT, comme indiqué ci-dessous:
if (! foo) // faire quelque chose si foo est faux else // faire quelque chose si foo est vrai
Les événements sont un sujet compliqué en JavaScript. Fini l'époque d'Inline sur clic
gestionnaires d’événements (sauf dans de très rares cas de "pages de démarrage"). Au lieu de cela, utilisez l'événement bouillonnant et la délégation.
Imaginons que vous disposiez d'une grille d'images nécessitant le lancement d'une fenêtre modale lightbox. Voici ce que vous ne devrait pas faire. Remarque: nous utilisons jQuery ici, en supposant que vous utilisez une bibliothèque similaire. Sinon, les mêmes principes de bouillonnement s'appliquent également à JavaScript en vanille.
Le HTML pertinent:
…
Le (mauvais) JavaScript:
$ ('a'). on ('click', function () callLightbox (this););
Ce code suppose que l'appel de la visionneuse implique le passage d'un élément d'ancrage faisant référence à l'image en taille réelle. Au lieu de se lier à chaque élément d’ancre, lier à la # grille-conteneur
élément à la place.
$ ("# grille-conteneur"). sur ("cliquez sur", "a", fonction (événement) callLightbox (event.target););
Dans ce code, les deux ce
et event.target
se référer à l'élément d'ancrage. Vous pouvez utiliser cette même technique avec n'importe quel élément parent. Assurez-vous simplement de définir l'élément qui devrait être la cible de l'événement.
La surutilisation des déclarations ternaires est assez courante en JavaScript et en PHP.
// javascript return foo.toString ()! == ""? vrai faux;
// php return (quelque chose ())? vrai faux;
Une expression de condition retourne toujours un vrai
ou faux
valeur, ce qui signifie que vous n'avez pas besoin d'ajouter explicitement vrai
/faux
comme valeurs ternaires. Au lieu de cela, vous pouvez simplement renvoyer la condition:
// javascript return foo.toString ()! == "";
// php renvoie quelque chose ();
sinon
les déclarations sont une partie centrale de la plupart des langues. Mais faire quelque chose de simple, comme assigner une valeur à une variable en fonction d'une condition - eh bien, ils risquent de gâcher votre code. Considérons le code suivant:
if ($ greeting) $ post-> message = 'Bonjour'; else $ post-> message = 'Au revoir';
Ce code peut être réduit à une ligne tout en maintenant la lisibilité à l'aide de l'opérateur ternaire, comme ceci:
$ post-> message = $ salutation? 'Bonjour au revoir';
C'est clair, concis et vous donne la fonctionnalité dont vous avez besoin.
Aussi utile que soit l'opérateur ternaire, la recommandation la plus importante est de ne pas en abuser! Le but du codage n’est pas de réduire votre logique en un minimum de lignes..
Regardons les choses en face: de nombreux niveaux de nidification sont laids et difficiles à maintenir / à lire. Le code suivant est un exemple relativement simplifié, mais ils s'aggravent avec le temps:
// anti-pattern $ error_message = null; if ($ this-> form_validation-> run ()) if ($ this-> upload-> do_upload ()) $ image = $ this-> upload-> get_info (); if (! $ this-> image-> create_thumbnail ($ image ['nom_fichier'], 300, 150)) $ error_message = 'Une erreur est survenue lors de la création de la vignette.'; else $ error_message = 'Une erreur est survenue lors du téléchargement de l'image.'; else $ error_message = $ this-> form_validation-> error_string (); // Affiche les messages d'erreur if ($ error_message! == null) $ this-> load-> view ('form', array ('error' => $ error_message,)); // Enregistrez la page else $ some_data ['image'] = $ image ['nom_fichier']; $ this-> some_model-> save ($ some_data);
C'est du code méchant, mais vous pouvez le rendre nettement plus propre en utilisant des exceptions, comme ceci:
try if (! $ this-> form_validation-> run ()) lance une nouvelle exception ($ this-> form_validation-> error_string ()); if (! $ this-> upload-> do_upload ()) lance une nouvelle exception ('Une erreur s'est produite lors du téléchargement de l'image.'); $ image = $ this-> upload-> get_info (); if (! $ this-> image-> create_thumbnail ($ image ['nom_fichier'], 300, 150)) émettre une nouvelle exception ('Une erreur s'est produite lors de la création de la vignette.'); // Afficher les messages d'erreur catch (Exception $ e) $ this-> load-> view ('form', array ('error' => $ e-> getMessage (),)); // Arrête l'exécution de la méthode avec return ou utilise exit return; // Vous en êtes bien loin, vous ne devez pas avoir de problèmes $ some_data ['image'] = $ image ['nom_fichier']; $ this-> some_model-> save ($ some_data);
Il peut s'agir du même nombre de lignes, mais cela permet un code considérablement plus lisible et maintenable. Cela évite également ces sessions de débogage difficiles, où vous avez raté un chemin possible à travers le si
déclaration. Rester simple!
Deuxième opinion: soyez très prudent lorsque vous utilisez des exceptions pour le contrôle de flux. Référez-vous ici pour des informations supplémentaires.
Faux
-Méthodes heureusesÊtre heureux d'exception est beaucoup plus avantageux que d'être faux faux.
Les développeurs Ruby ou Python sont habitués à surveiller les exceptions triviales. Bien que cela semble fastidieux, c'est en fait une très bonne chose. Si quelque chose ne va pas, une exception est levée et vous savez instantanément où est le problème..
En PHP, et en particulier lorsque vous utilisez des frameworks plus anciens, tels que CodeIgniter, vous obtenez ce que je qualifie de "code faux-heureux" (par opposition à un bonheur exceptionnel). Au lieu d’avoir une exception à la figure, elle renvoie simplement un faux
value et attribue la chaîne d'erreur à une autre propriété. Cela vous oblige à le sortir de la classe en utilisant un get_error ();
méthode.
Être heureux d'exception est beaucoup plus avantageux que d'être faux faux. Si une erreur survient dans votre code (par exemple: impossible de se connecter à S3 pour télécharger une image ou si une valeur est vide, etc.), émettez une exception. Vous pouvez également lancer des types d’exceptions spécifiques en étendant la Exception
classe, comme si:
La classe CustomException étend l'exception
Le lancement d'une exception personnalisée facilite considérablement le débogage.
Il est commun d'utiliser si
instructions pour contrôler le chemin d'exécution d'une fonction ou d'une méthode. Il est tentant de tester une condition et d'exécuter beaucoup de code lorsque la condition a pour résultat vrai
, seulement pour revenir dans le autre
déclaration. Par exemple:
function une fonction ($ param) if ($ param == 'OK') $ this-> doQuelque chose (); retourne vrai; else return false;
Ce type de solution représente toutefois un potentiel pour le code spaghetti. Vous pouvez rendre ce code plus facile à lire en inversant la condition. Voici la meilleure version:
function someFunction ($ param) if ($ param! = 'OK') renvoie false; $ this-> doQuelque chose (); retourne vrai;
N'est-ce pas plus facile à lire? C'est un simple changement qui fait une différence radicale dans la lisibilité de votre code.
tandis que
pour les itérations simplesle pour
La boucle est couramment utilisée lorsque vous avez besoin, par exemple, d’un compteur. Voici un simple pour
boucle:
pour (var i = 0; i < x; i++) …
Il y a de très bonnes raisons d'utiliser un pour
boucle, mais un tandis que
boucle peut être mieux si vous avez juste besoin de quelque chose de simple, comme ceci:
var i = x; alors que je--) …
Cela ne fonctionne pas dans toutes les situations, mais c'est une alternative.
C'est facilement l'une des erreurs les plus fréquentes commises par les nouveaux arrivants.
Une méthode est l'unité de travail d'un objet, et limiter vos méthodes à une taille maintenable facilite la lecture et la maintenance de votre code. Jetez un oeil à la méthode de monstre suivante:
classe SomeClass fonction monsterMethod () if ($ weArePilots) $ this-> goAndDressUp (); $ this-> washYourTeeth (); $ this-> cleanYourWeapon (); $ this-> takeYourHelmet (); if ($ this-> helmetDoesNotFit ()) $ this-> takeAHat (); else $ this-> installHelmet (); $ this-> chekcYourKnife (); if ($ this-> myAirplain () == "F22") $ this-> goToArmyAirport (); else $ this-> goToCivilianAirport (); $ this-> but (); $ this-> prepare (); $ this-> fire ();
Envisagez de diviser cette méthode monstre en morceaux plus petits et descriptifs, chacun étant responsable de l'exécution d'une action bien abstraite. C'est facilement l'une des erreurs les plus fréquentes commises par les nouveaux arrivants.
classe SomeClass function monsterMethod () if ($ weArePilots) $ this-> prepareYourself (); $ this-> tryHelmet (); $ this-> findYourAirport (); $ this-> fightEnemy (); fonction privée prepareYourself () $ this-> goAndDressUp (); $ this-> washYourTeeth (); $ this-> cleanYourWeapon (); $ this-> chekcYourKnife (); fonction privée tryHelmet () $ this-> takeYourHelmet (); if ($ this-> helmetDoesNotFit ()) $ this-> takeAHat (); else $ this-> installHelmet (); fonction privée findYourAirport () if ($ this-> myAirplain () == "F22") $ this-> goToArmyAirport (); else $ this-> goToCivilianAirport (); fonction privée fightEnemy () $ this-> aim (); $ this-> prepare (); $ this-> fire ();
On y va: plus propre et plus facile à déboguer!
Trop de niveaux d'imbrication rendent le code difficile à lire et à maintenir. Considérer ce qui suit:
fonction doQuelque chose () if ($ someCondition) if ($ someOtherCondition) if ($ yetSomeOtherCondition) doSomethingSpecial (); doSomethingElse ();
Vous pouvez vous référer au conseil n ° 10 pour rendre ce code plus facile à lire en inversant certaines des conditions..
fonction doQuelque chose () if (! $ someCondition) return false; if (! $ someOtherCondition) return false; if ($ yetSomeOtherCondition) doQuelque chose de spécial (); doSomethingElse ();
Ce code est considérablement plus propre et produit les mêmes résultats qu'auparavant.
Quand vous vous retrouvez avec imbriqué si
Déclarations, examinez attentivement votre code; votre méthode peut effectuer plus d'une tâche. Voici un exemple:
function someFunc () if ($ oneThing) $ this-> doSomething (); if ($ anotherThing) $ this-> doSomethingElse ();
Dans ces cas, extrayez les méthodes imbriquées dans leur propre méthode:
function someFunc () if ($ oneThing) $ this-> doSomething (); $ this-> doAnotherThing ($ anotherThing); private doAnotherThing ($ anotherThing) if ($ anotherThing) $ this-> doSomethingElse ();
Les nombres magiques et les chaînes sont diaboliques. Définir des variables ou des constantes avec les valeurs que vous souhaitez utiliser dans votre code.
Au lieu de cela:
function someFunct () $ this-> order-> set (23); $ this-> order-> addProduct ('superComputer'); $ this-> shoppingList-> add ('superordinateur');
Spécifiez la signification de ces nombres et de ces chaînes et affectez-les à une variable portant un nom explicite, comme ceci:
function someFunct () $ orderId = 23; $ selectedProductName = 'superComputer'; $ this-> order-> set ($ orderId); $ this-> order-> addProduct ($ selectedProductName); $ this-> shoppingList-> add ($ selectedProductName);
Certains pourraient prétendre que nous créons inutilement des variables, mais l’atteinte en termes de performances est négligeable. La lisibilité est toujours prioritaire. Rappelez-vous: n'optimisez pas la performance tant que vous ne pouvez pas expliquer pourquoi c'est nécessaire.
Utilisez les fonctions de tableau intégrées au lieu de pour chaque()
.
Pas idéal:
foreach (& $ myArray as $ key => $ element) if ($ element> 5) unset ($ myArray [$ key]);
Meilleur:
$ myArray = array_filter ($ myArray, function ($ element) return $ element <= 5;);
PHP propose une variété de méthodes de tableau. Ils sont déroutants au début, mais prenez une journée et essayez d’en apprendre le plus possible..
Il est facile d’abuser des variables, mais rappelez-vous que les variables sont stockées en mémoire. Pour chaque variable que vous créez, le système doit allouer de la mémoire pour cette variable. Regardez ce code:
fonction publique get_posts () $ query = $ this-> db-> get ('posts'); $ result = $ query-> result (); return $ result;
le $ résultat
variable n'est pas nécessaire. Le code suivant omet cette variable:
fonction publique get_posts () $ query = $ this-> db-> get ('posts'); return $ query-> result ();
La différence est subtile, mais nous avons pu améliorer cet exemple simple. Nous avons gardé le $ requête variable car elle concerne la base de données, alors que $ résultat plus lié à notre logique.
Rien de moins est une odeur de code.
Une base de données est conçue pour travailler avec des données; utiliser ses outils et ses compétences pour rendre votre application plus efficace.
Par exemple, vous pouvez éviter les requêtes redondantes dans la base de données dans de nombreuses circonstances. La plupart des scripts plug-and-play de gestion des utilisateurs utilisent deux requêtes d'enregistrement d'utilisateur: une pour vérifier si le courrier électronique / nom d'utilisateur existe déjà et l'autre pour l'ajouter à la base de données. Une meilleure approche consiste à définir le champ Nom d'utilisateur sur UNIQUE
. Vous pouvez ensuite utiliser les fonctions natives de MySQL pour vérifier si l'enregistrement a été ajouté à la base de données..
Les jours de nommer vos variables X
, y
, z
sont terminés (à moins, bien sûr, que vous ayez affaire à un système de coordonnées). Une variable représente une partie importante de votre logique. Vous ne voulez pas taper un nom long? Obtenez un meilleur IDE. Les IDE modernes remplissent automatiquement les noms de variables en un clin d'œil.
Toujours coder pour six mois à partir de maintenant. Êtes-vous certain que vous vous souviendrez de ce que cela
$ sut
variables se réfère à un an à partir de maintenant? Probablement pas: soyez descriptif. Rien de moins est une odeur de code.
Les erreurs se produisent; la clé est d'apprendre d'eux.
Nommez vos méthodes avec des verbes représentant l'action qu'ils effectuent. Le concept principal est l'exact opposé du schéma de nommage des variables. Utilisez un nom court, mais descriptif, dans un champ étendu (par exemple, méthodes publiques) et utilisez un nom plus long et plus détaillé dans un champ court (par exemple, méthodes privées / protégées). Cela aide à faire lire votre code comme une prose bien écrite.
Évitez également toute langue autre que l'anglais lorsque vous nommez vos méthodes. Il est ennuyeux de lire des noms de fonction comme 什麼 () ou делатьчтото () dans votre projet. Il peut être impossible pour les autres programmeurs de comprendre votre intention. Bien que cela puisse paraître arrogant, pour le meilleur ou pour le pire, l'anglais est la langue de code adoptée. Essayez de l'utiliser, si nous travaillons sur une grande équipe.
Enfin, la structure du code est tout aussi importante pour la lisibilité et la maintenabilité que tout ce dont nous avons parlé aujourd'hui. Voici deux recommandations:
"Je n'ai jamais fait une erreur de programmation stupide." -- Jamais personne.
Les erreurs se produisent; la clé est d'apprendre d'eux. Chez Nettuts +, nous avons commis et continuerons de faire des erreurs. Notre espoir est que vous tiriez les leçons de nos erreurs pour pouvoir les éviter à l'avenir. Mais, pour être honnête, le meilleur moyen d’apprendre les meilleures pratiques est de faire soi-même les erreurs.!
Merci d'avoir lu!