JavaScript est un langage de programmation imbattable qui peut être utilisé pour le développement web, le développement d'applications mobiles (PhoneGap, Appcelerator), le développement côté serveur (Node.js et Wakanda), etc. JavaScript est aussi le premier langage pour de nombreux débutants qui entrent dans le monde de la programmation. Il peut être utilisé à la fois pour afficher de simples boîtes d'alerte dans le navigateur et pour contrôler des robots via nodebot ou nodruino. Les développeurs capables d'écrire du code JavaScript bien structuré et performant sont désormais devenus les personnes les plus recherchées sur le marché du travail.

Dans cet article, je vais partager quelques astuces, trucs et bonnes pratiques JavaScript. À quelques exceptions près, elles s'appliquent à la fois aux moteurs JavaScript des navigateurs et aux interpréteurs JavaScript côté serveur.

L'exemple de code dans cet article a été testé sur la dernière version de Google Chrome 30 (V8 3.20.17.15).

1. Utilisez toujours lors de l'affectation d'une variable pour la première foisvarkeyword

Si une variable est affectée sans avoir été déclarée, elle devient par défaut une nouvelle variable globale. Essayez d'éviter d'utiliser des variables globales.

2. Utilisez===au lieu de==

==et!=L'opérateur convertit automatiquement les types de données lorsque c'est nécessaire. Mais===et!==ne le font pas. Ils comparent à la fois la valeur et le type de données en même temps, ce qui les rend aussi [plus rapides] que==et!=, 0, false, NaN et les chaînes vides s'évaluent toutes à false dans un contexte booléen

[10] === 10    // is false
[10]  == 10    // is true
'10' == 10     // is true
'10' === 10    // is false
 []   == 0     // is true
 [] ===  0     // is false
 '' == false   // is true but true == "a" is false
 '' === false  // is false
 

3, undefined、null, 0, false, NaN et les chaînes vides s'évaluent toutes à false dans un contexte booléen

4. Utilisez des points-virgules à la fin des lignes

La vérité sur les points-virgules en JavaScript5. Utiliser les constructeurs d'objets。

5. Utiliser les constructeurs d'objets

function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");

6. Faites attention avectypeof、instanceofetcontructor

  • typeofrenvoie égalementtypeof null, la plupart des types d'objets (Array, Date, etc.) renvoient aussiobject: propriété prototype interne, peut être réécrite par le codeobject
  • contructor: opérateur JavaScript, recherche les constructeurs dans la chaîne de prototypes, renvoie s'il est trouvé
  • instanceof, sinon renvoietruefalse
var arr = ["a", "b", "c"];
typeof arr;   // 返回 "object" 
arr instanceof Array // true
arr.constructor();  //[]

7. Utiliser les fonctions auto-invoquées

La fonction s'exécute automatiquement immédiatement après sa création, généralement appelée fonction anonyme auto-invoquée ou expression de fonction immédiatement invoquée (IIFE). Le format est le suivant :

(function(){
    // 置于此处的代码将自动执行
})();  
(function(a,b){
    var result = a+b;
    return result;
})(10,20)

8. Obtenir aléatoirement un membre d'un tableau

var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var  randomItem = items[Math.floor(Math.random() * items.length)];

9. Obtenir un nombre aléatoire dans une plage spécifiée

Cette fonctionnalité est particulièrement utile lors de la génération de données fictives pour les tests, comme des nombres de salaire dans une plage spécifiée.

var x = Math.floor(Math.random() * (max - min + 1)) + min;

10. Générer un tableau de nombres de 0 à une valeur spécifiée

var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++) < max;);  // numbers = [1,2,3 ... 100]

11. Générer une chaîne alphanumérique aléatoire

function generateRandomAlphaNum(len) {
    var rdmString = "";
    for( ; rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
    return  rdmString.substr(0, len);
}

12. Mélanger l'ordre d'un tableau numérique

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* numbers 数组将类似于 [120, 5, 228, -215, 400, 458, -85411, 122205]  */

Ici, la fonction de tri de tableau intégrée de JavaScript est utilisée. Une meilleure approche consiste à utiliser un code dédié (comme l'algorithme de Fisher-Yates). Voir la discussion sur StackOverflowcette discussion。

13. Supprimer les espaces d'une chaîne

Java, C#, PHP et d'autres langages ont tous des fonctions dédiées pour supprimer les espaces d'une chaîne, mais JavaScript n'en a pas. Vous pouvez utiliser le code suivant pour ajouter àStringl'objet atrimfonction :

String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};

Les nouveaux moteurs JavaScript ont déjàtrim()des implémentations natives de.

14. Concaténer des tableaux

var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值为  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

15. Convertir un objet en tableau

var argArray = Array.prototype.slice.call(arguments);

16. Vérifier s'il s'agit d'un nombre

function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

17. Vérifier s'il s'agit d'un tableau

function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

Mais sitoString()la méthode a été redéfinie, cela ne fonctionnera pas. Vous pouvez également utiliser la méthode suivante :

Array.isArray(obj); // its a new Array method

Si le navigateur n’utilise pas de frames, vous pouvez également utiliserinstanceof, mais si le contexte est trop complexe, cela peut aussi échouer.

var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]  
// myArray 的构造器已经丢失,instanceof 的结果将不正常
// 构造器是不能跨 frame 共享的
arr instanceof Array; // false

18. Obtenir les valeurs maximale et minimale dans un tableau

var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; 
var maxInNumbers = Math.max.apply(Math, numbers); 
var minInNumbers = Math.min.apply(Math, numbers);

19. Vider un tableau

var myArray = [12 , 222 , 1000 ];  
myArray.length = 0; // myArray will be equal to [].

20. Ne supprimez pas directement depuis le tableaudeleteouremoveéléments

Si vous utilisez directement sur les éléments d’un tableaudelete, cela ne supprime pas réellement, mais met l’élément àundefined. Pour supprimer des éléments d’un tableau, vous devez utilisersplice。

Jamais :

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
delete items[3]; // return true 
items.length; // return 11 
/* items 结果为 [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */

À la place :

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
items.splice(3,1) ; 
items.length; // return 10 
/* items 结果为 [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119]

Lors de la suppression de propriétés d'objet, vous pouvez utiliserdelete。

21. Utiliserlengthla propriété pour tronquer un tableau

Dans l'exemple précédent, en utilisantlengthla propriété a vidé le tableau. Vous pouvez également l'utiliser pour tronquer le tableau :

var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];  
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

En même temps, si vous rendez lalengthpropriété plus grande, la longueur du tableau augmentera, et il utiliseraundefinedpour remplir en tant que nouveaux éléments.lengthest une propriété accessible en écriture.

myArray.length = 10; // the new array length is 10 
myArray[myArray.length - 1] ; // undefined

22. Utiliser les opérateurs logiques ET/OU dans les conditions

var foo = 10;  
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething(); 
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

L'opérateur OU logique peut également être utilisé pour définir des valeurs par défaut, telles que des valeurs par défaut pour les paramètres de fonction.

function doSomething(arg1){ 
    arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
}

23. Fairemap()les méthodes de fonction parcourent les données

var squares = [1,2,3,4].map(function (val) {  
    return val * val;  
}); 
// squares will be equal to [1, 4, 9, 16]

24. Conserver un nombre spécifié de décimales

var num =2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432

Notez quetoFixec()ce qui est renvoyé est une chaîne, pas un nombre.

25. Problèmes de calcul en virgule flottante

0.1 + 0.2 === 0.3 // is false 
9007199254740992 + 1 // is equal to 9007199254740992
9007199254740992 + 2 // is equal to 9007199254740994

Pourquoi ? Parce que 0.1+0.2 est égal à 0.30000000000000004. Les nombres JavaScript sont construits selon la norme IEEE 754, et en interne sont tous des représentations en virgule flottante 64 bits. Pour plus de détails, voirComment les nombres sont encodés en JavaScript.

Vous pouvez utilisertoFixed()ettoPrecision()pour résoudre ce problème.

26. Vérifier les propriétés d'un objet avec une boucle for-in

L'utilisation suivante peut empêcher l'itération d'entrer dans les propriétés du prototype de l'objet.

for (var name in object) {  
    if (object.hasOwnProperty(name)) { 
        // do something with name
    }  
}

27. Opérateur virgule

var a = 0; 
var b = ( a++, 99 ); 
console.log(a);  // a will be equal to 1 
console.log(b);  // b is equal to 99

28. Stocker temporairement des variables pour le calcul et la recherche

Dans les sélecteurs jQuery, vous pouvez stocker temporairement des éléments DOM entiers.

var navright = document.querySelector('#right'); 
var navleft = document.querySelector('#left'); 
var navup = document.querySelector('#up'); 
var navdown = document.querySelector('#down');

29. Vérifier les entrées à l'avanceisFinite()parameters

isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10);   // true
isFinite(undefined);  // false
isFinite();   // false
isFinite(null);  // true,这点当特别注意

30. Éviter d'utiliser des nombres négatifs comme indices dans les tableaux

var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ; // from is equal to -1
numbersArray.splice(from,2); // will return [5]

Notez que le paramètre index transmis àsplicene doit pas être négatif ; lorsqu'il est négatif, les éléments seront supprimés à partir de la fin du tableau.

31. Utiliser JSON pour la sérialisation et la désérialisation

var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson 结果为 "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */
var personFromString = JSON.parse(stringFromPerson);
/* personFromString 的值与 person 对象相同  */

32. Ne pas utilisereval()ou les constructeurs de fonctions

eval()et le constructeur de fonction (Functionconstructeur) ont un surcoût important ; chaque fois qu'ils sont appelés, le moteur JavaScript doit convertir le code source en code exécutable.

var func1 = new Function(functionCode);
var func2 = eval(functionCode);

33. Éviter d'utiliserwith()

Utilisationwith()peut ajouter des variables à la portée globale, donc s'il existe d'autres variables portant le même nom, cela créera de la confusion et les valeurs seront également écrasées.

34. Ne pas utiliser for-in sur les tableaux

À éviter :

var sum = 0;  
for (var i in arrayNumbers) {  
    sum += arrayNumbers[i];  
}

À la place :

var sum = 0;  
for (var i = 0, len = arrayNumbers.length; i < len; i++) {  
    sum += arrayNumbers[i];  
}

Un autre avantage est que,ietlenles deux variables sontfordans la première déclaration de la boucle, et toutes les deux ne sont initialisées qu'une seule fois, ce qui est plus rapide que l'approche suivante :

for (var i = 0; i < arrayNumbers.length; i++)

35. Passez àsetInterval()etsetTimeout()utiliser une fonction au lieu d'une chaîne lorsque

Si vous passezsetTimeout()etsetInterval()une chaîne, ils utiliseront une méthode similaire àevalpour la convertir, ce qui sera certainement plus lent, donc ne l'utilisez pas :

setInterval('doSomethingPeriodically()', 1000);  
setTimeout('doSomethingAfterFiveSeconds()', 5000);

Utilisez plutôt :

setInterval(doSomethingPeriodically, 1000);  
setTimeout(doSomethingAfterFiveSeconds, 5000);

36. Utilisezswitch/caseau lieu d'une grande pile deif/else

Lorsque la condition comporte plus de deux branches, utilisezswitch/casec'est plus rapide, plus élégant et meilleur pour l'organisation du code. Bien sûr, s'il y a plus de 10 branches, ne pas utiliserswitch/caseit.

37. Dansswitch/caseutilisez des plages numériques dans

En fait,switch/casedans lecasecondition, on peut aussi l'écrire comme ceci :

function getCategory(age) {  
    var category = "";  
    switch (true) {  
        case isNaN(age):  
            category = "not an age";  
            break;  
        case (age >= 50):  
            category = "Old";  
            break;  
        case (age <= 20):  
            category = "Baby";  
            break;  
        default:  
            category = "Young";  
            break;  
    };  
    return category;  
}  
getCategory(5);  // 将返回 "Baby"

38. Utiliser un objet comme prototype d'un autre objet

De la manière suivante, un objet donné peut être passé en paramètre pour créer un nouvel objet en l'utilisant comme prototype :

function clone(object) {  
    function OneShotConstructor(){}; 
    OneShotConstructor.prototype = object;  
    return new OneShotConstructor(); 
} 
clone(Array).prototype ;  // []

39. Fonctions de conversion de champs HTML

function escapeHTML(text) {  
    var replacements= {"<": "<", ">": ">","&": "&", "\"": """};                      
    return text.replace(/[<>&"]/g, function(character) {  
        return replacements[character];  
    }); 
}

40. Ne pas utiliser try-catch-finally à l'intérieur de boucles

Dans try-catch-finally, la partie catch affecte l'exception à une variable pendant l'exécution, et cette variable est construite comme une nouvelle variable dans la portée d'exécution.

À éviter :

var object = ['foo', 'bar'], i;  
for (i = 0, len = object.length; i <len; i++) {  
    try {  
        // do something that throws an exception 
    }  
    catch (e) {   
        // handle exception  
    } 
}

À la place :

var object = ['foo', 'bar'], i;  
try { 
    for (i = 0, len = object.length; i <len; i++) {  
        // do something that throws an exception 
    } 
} 
catch (e) {   
    // handle exception  
}

41. Faites attention à définir un délai d'attente lors de l'utilisation de XMLHttpRequests

Lorsque des XMLHttpRequests sont en cours d'exécution et n'ont pas de réponse pendant longtemps (par exemple lorsqu'un problème réseau survient), la connexion doit être interrompue. Cela peut être fait viasetTimeout()pour ce faire :

var xhr = new XMLHttpRequest (); 
xhr.onreadystatechange = function () {  
    if (this.readyState == 4) {  
        clearTimeout(timeout);  
        // do something with response data 
    }  
}  
var timeout = setTimeout( function () {  
    xhr.abort(); // call error callback  
}, 60*1000 /* timeout after a minute */ ); 
xhr.open('GET', url, true);  
xhr.send();

Notez également que vous ne devez pas lancer plusieurs XMLHttpRequests en même temps.

42. Gérer les délais d'attente WebSocket

Normalement, après qu'une connexion WebSocket est créée, s'il n'y a aucune activité dans les 30 secondes, le serveur mettra la connexion en timeout, et fermera les connexions qui n'ont aucune activité pendant une période donnée.

Pour éviter que cela ne se produise, vous pouvez envoyer un message vide au serveur à intervalles réguliers. Cela peut être réalisé avec les deux fonctions suivantes : une pour maintenir la connexion, et une spécifiquement pour mettre fin à cet état.

var timerID = 0; 
function keepAlive() { 
    var timeout = 15000;  
    if (webSocket.readyState == webSocket.OPEN) {  
        webSocket.send('');  
    }  
    timerId = setTimeout(keepAlive, timeout);  
}  
function cancelKeepAlive() {  
    if (timerId) {  
        cancelTimeout(timerId);  
    }  
}

keepAlive()La fonction peut être placée à la fin de la connexion WebSocketonOpen()méthode,cancelKeepAlive()et placée à laonClose()toute fin de la méthode.

43. Gardez toujours à l'esprit que les opérateurs sont plus rapides que les appels de fonctions ; utilisez VanillaJS

Par exemple, en général, ne faites pas ceci :

var min = Math.min(a,b); 
A.push(v);

Vous pouvez le remplacer par ceci :

var min = a < b ? a : b; 
A[A.length] = v;

44. Faites attention à la structure du code pendant le développement, et vérifiez et compressez le code JavaScript avant la mise en production

N'oubliez pas d'utiliser un formateur de code lorsque vous écrivez du code. Utilisez JSLint (un outil de vérification de syntaxe) et minifiez le code avant la mise en production (par exemple, avec JSMin). Remarque : UglifyJS est désormais généralement recommandé pour la minification du code (https://github.com/mishoo/UglifyJS2)

45. JavaScript est vaste et profond ; voici quelques bonnes ressources d'apprentissage

  • Ressource Code Academy : http://www.codecademy.com/tracks/javascript
  • Écrit par Marijn HaverbekeEloquent JavaScript:http://eloquentjavascript.net/
  • Écrit par John ResigAdvanced JavaScript:http://ejohn.org/apps/learn/

Source : http://www.codeceo.com/article/javascript-45-tips.html