JavaScript, s'il ne l'est que par défaut, est l'un des langages de programmation les plus populaires. Au fil des ans, c'est devenu un cauchemar, et dans une certaine mesure, c'est vrai! Cependant, plus souvent qu'autrement, ce que les gens veulent dire, c'est que l'API DOM est un cauchemar. Néanmoins, il y a une poignée d'erreurs à plat dans la langue.
Je voudrais faire une note que j'aime JavaScript. Cet article est uniquement destiné à l’amusement et à la connaissance de ses lacunes..
Nous allons commencer par un coup amusant au choix du nom. Alors qu'il s'appelait à l'origine Mocha, puis LiveScript, il a par la suite été remplacé par JavaScript. Selon l’histoire, ses similitudes avec le nom Java résultaient d’une collaboration entre Netscape et Sun, en échange de l’intégration du runtime Java dans le navigateur Netscape. Il a également été noté que le nom est venu, presque comme une blague, en raison de la rivalité entre LiveScript et Java pour les scripts côté client.
Néanmoins, des milliers de commentaires "JavaScript n'a rien à voir avec Java" sur les forums du Web!
Considère ceci…
console.log (typeof null); // objet
Cela n'a aucun sens. Si null est l'absence d'une valeur, alors comment son type pourrait-il être "objet"? La réponse simple est qu’il s’agit d’une erreur simple qui remonte à la première version de JavaScript - une erreur qui a même été reportée de manière incorrecte sur le code JScript de Microsoft..
NaN, comme on pouvait s'y attendre, fait référence à une valeur qui n'est pas un nombre légal. Le problème est que NaN n'est égal à rien… y compris lui-même.
console.log (NaN === NaN); // faux
Cela devrait être faux. Au lieu de cela, si vous voulez déterminer si une valeur est effectivement NaN, vous pouvez utiliser la fonction isNaN ()..
Mettre à jour: Après avoir lu quelques-uns des commentaires brillants, en particulier ceux concernant NaN étant similaires à l'infini, il est alors parfaitement logique que NaN ne soit pas égal à lui-même. Mais cela peut encore être déroutant. Reportez-vous aux commentaires pour une discussion approfondie sur ce sujet.!
La dépendance vis-à-vis des variables globales est généralement considérée comme la pire partie de JavaScript. Pour les projets simples, un peu comme les astuces sur ce site, cela ne fait pas vraiment une différence. Cependant, le véritable fardeau des globals entre en jeu lorsque vous commencez à référencer plusieurs scripts, sans savoir comment ils ont été créés ou nommés. S'il se trouve qu'ils partagent le même nom que l'une de vos variables, votre programme générera une sorte d'erreur..
"Le problème avec JavaScript n'est pas simplement qu'il les autorise (variables globales), il les requiert." - Crockford
D'accord - celui-ci n'est pas la faute de JavaScript. J'ai triché un peu. C'est à cause des vendeurs de navigateurs. Cela dit, la détection de chaînes d’agent d’utilisateur est très courante en JavaScript; il est donc important de savoir à quoi vous avez affaire. Il ne fait probablement pas partie de cette liste, mais peu importe. C'est bon à savoir.
Celui-ci n'est pas autant une erreur que c'était une décision inévitable. Par exemple, ouvrez Safari, accédez à Web Inspector et connectez la chaîne de l'agent utilisateur à la console..
console.log (navigator.userAgent); // Mozilla / 5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit / 531.21.8 (KHTML, comme Gecko) Version / 4.0.4 Safari / 531.21.10
Notez que la première chaîne de caractères: Mozilla / 5.0. Pourquoi Safari l'identifierait-il comme un navigateur basé sur Mozilla? Bien que plus tard, il s'identifie correctement, cela n'explique toujours pas pourquoi ils s'embarrasseraient d'induire les programmeurs en erreur. En fait, vous constaterez que la plupart des navigateurs s'identifient comme Mozilla. La réponse remonte à une décennie et, encore une fois, est moins une erreur que davantage une circonstance inévitable..
Pour ceux qui ne sont pas familiers, une chaîne d'agent utilisateur sert simplement à identifier le navigateur et sa version. Par exemple, le tout premier navigateur, Mosaic, avait une chaîne d'agent utilisateur qui ressemblait à ceci:
Mosaïque / 0.9 // nom du navigateur / numéro de version
Cela est parfaitement logique. Et lorsque Netscape est arrivé sur les lieux, ils ont conservé l'utilisation de Mosaic et ajouté une section de type de chiffrement..
Mozilla / 2.02 [en] (Win95; I) // nom du navigateur / version / cryptage
Jusqu'ici tout va bien. Les problèmes sont entrés en jeu lorsque, attendez, Internet Explorer 3 a été publié. Gardez à l'esprit que, lors de son lancement, Netscape était le navigateur le plus populaire disponible. En fait, de nombreux serveurs et programmes implémentaient déjà la détection d’agent d’utilisateur afin d’identifier Netscape. Bien qu’il s’agisse d’un sujet très controversé aujourd’hui, ce n’était pas vraiment un problème. Si IE avait utilisé sa propre chaîne d'agent utilisateur, cela aurait ressemblé à ceci:
MSIE / 3.0 (Win95; U)
Cela les aurait laissés dans un désavantage énorme, car Netscape était déjà identifié par de nombreux serveurs. En tant que tels, les développeurs ont décidé d’identifier le navigateur de manière incorrecte en tant que Mozilla, puis d’ajouter un ensemble d’informations supplémentaires le qualifiant d’Internet Explorer..
Mozilla / 2.0 (compatible; MSIE 3.0; Windows 95)
De nos jours, la détection d’agent d’utilisateur est un dernier effort, et elle est donc considérée avec précision pour cette raison. Vous constaterez que la plupart des navigateurs ont suivi l'exemple d'IE en s'identifiant comme Mozilla. Pensez-y comme une réaction en chaîne.
Je vous recommande fortement de lire "Histoire de la chaîne utilisateur-agent" de Nicholas Zakas si vous souhaitez approfondir.
Considérons le code suivant:
// Crée une fonction qui appellera une fonction dont le nom est égal au paramètre fn. fonction foo (fn) if (type de fn === "fonction") fn (); // Créer un objet avec une propriété et une méthode. var bar = barbar: "Bonjour le monde!", méthode: function () alert (this.barbar); ; méthode de barre (); // Alertes Bonjour, le monde! toto (méthode de bar); // Si nous appelons la fonction foo add pass the "bar.method", elle alerte en quelque sorte "undefined". foo (function () bar.method ();); // alerte Bonjour, Monde, après
La raison pour laquelle foo (bar.method) ne rend pas le même résultat est que la fonction méthode sera appelée comme méthode de l'objet window plutôt que comme barre. Pour résoudre ce problème, nous devons appeler bar.method () à partir de la fonction anonyme passée..
Merci beaucoup à Jeremy McPeak pour m'avoir signalé cette erreur.
JavaScript partage de nombreuses similitudes avec Java - l'un d'eux étant l'ensemble des opérateurs au niveau des bits..
Considérons le premier élément, &; il serait beaucoup plus efficace d'utiliser l'opérateur &&, car c'est plus rapide. En effet, JavaScript n’est pas identique à Java et n’a pas d’entiers. En tant que tel, un processus relativement long est nécessaire pour convertir l'opérande, en faire quelque chose, puis le reconvertir.
C'est pourquoi vous pouvez vous en tirer en utilisant & pour "et", et | pour "ou" - même si vous devriez utiliser && et ||.
Ce n'est peut-être pas une erreur de JavaScript, mais cela rend le processus d'apprentissage particulièrement difficile pour les débutants. Des valeurs comme nulles, fausses et non définies signifient presque la même chose, mais certaines différences peuvent être déroutantes à comprendre..
Pour tester, ouvrez la console dans Firefox et trouvez le booléen des éléments suivants.
!!(0); // false !! (false); // false !! ("); // false !! (null); // false !! (indéfini); // false !! (NaN); // false
Veuillez noter que toute autre valeur sera interprétée comme une vérité..
Plus qu'une erreur, ces nombreuses valeurs de fausseté sont source de confusion!
D'accord, d'accord - je suis à 99% de taquiner avec l'en-tête ci-dessus. Cependant, JavaScript présente quelques problèmes mineurs lors de l'utilisation de nombres décimaux, par exemple des opérations telles que les transactions monétaires. Par exemple, ouvrez votre console et enregistrez ".2 + .4". Nous nous attendons à ce qu'il affiche ".6", correct? Et bien ça le fait, et ça ne marche pas!
console.log (.2 + .4); // 0.6000000000000001
Comment venir? À un niveau élevé, c'est parce que JavaScript utilise la norme IEEE pour l'arithmétique binaire en virgule flottante. Comme vous, je ne comprends probablement pas tout à fait exactement ce que cela spécifie, mais je sais seulement que, s’agissant des fractions décimales, les résultats peuvent légèrement différer de ce à quoi vous pourriez vous attendre. Gardez à l'esprit que l'arithmétique des nombres entiers est parfaite, ce n'est donc pas un gros problème..
En ce qui concerne votre style de codage, c’est exactement cela: ton style. Certaines personnes préfèrent placer leurs accolades sur la même ligne que le contrôle, d’autres préfèrent que cela se passe tout seul..
// accolades à droite return foo: bar; // accolades sur leur propre ligne return foo: bar;
En fonction du premier livre de développement Web que nous avons lu ou de la façon dont notre professeur nous l’a enseigné, il est parfaitement acceptable d’utiliser l’une des méthodes décrites ci-dessus, voire une combinaison des deux. Le problème avec JavaScript est que ce n'est pas votre choix!
J'ai appris cet exemple particulier lors d'une conférence que Doug Crockford a donnée il y a environ un an. Considérons la déclaration de retour ci-dessus. Croyez-le ou non, ils ne sont pas égaux. Ne me crois pas? Essayez ceci. Ajouter ce qui suit à une page HTML.
var foo = function () return a: 'b'; (); alerte (foo.a); // b
Le code ci-dessus crée simplement une variable appelée foo, qui est égale à l'objet renvoyé. Lorsque nous alertons (foo.a), nous voyons, comme prévu, une zone d’alerte avec la valeur 'b.' Maintenant, prenez simplement cette accolade d’ouverture, de la déclaration return, et ramenez-la à sa propre ligne, comme.
return a: 'b';
Si vous l'exécutez à nouveau dans votre navigateur, vous recevrez une erreur Firebug, indiquant que "foo n'est pas défini". Que se passe-t-il!? :)
Alors, pourquoi JavaScript fait-il cela? C'est à cause de quelque chose appelé "insertion de point-virgule". JavaScript va essentiellement tenter de corriger notre mauvais code. Si, par exemple, il pense que vous avez oublié un point-virgule de clôture, il va continuer et l'ajouter pour vous. Bien que cela ait été conçu à l'origine pour être pratique, en particulier pour les nouveaux utilisateurs de JavaScript, c'est en fait une très mauvaise chose si vous n'avez pas le contrôle de votre propre code, comme démontré ci-dessus.
Dans notre exemple, il n’existe aucun moyen de déterminer pourquoi foo.a renvoie «indéfini». Maintenant que nous sommes conscients de l’insertion de point-virgule, c’est parce que JavaScript ajoute un point-virgule à la fin de la déclaration return..
revenir; // JS ajoute incorrectement ce point-virgule. un B'; // Cela va ajouter un point-virgule ici aussi, parce qu'il ne réalise pas que c'est un objet. ;
Donc, si nous revenons immédiatement, il n’a aucune idée de ce que la propriété "a" est, ce qui donne "indéfini".
Comme je l'ai mentionné au début de cet article, j'aime JavaScript et je l'utilise quotidiennement. Mais cela ne veut pas dire qu’il n’ya pas d’erreurs terribles dans la langue. J'aimerais entendre vos pensées dans les commentaires! Merci d'avoir lu. Retweets et Diggs sont toujours appréciés! Merci beaucoup à Jeremy McPeak, Doug Crockford, Nicholas Zakas et John Resig: J'ai fait référence à vos tutoriels et livres lors de la préparation de cet article..