JavaScript es un lenguaje de programación excepcional a nivel mundial, que puede utilizarse para desarrollo web, desarrollo de aplicaciones móviles (PhoneGap, Appcelerator), desarrollo del lado del servidor (Node.js y Wakanda), etc. JavaScript es también el primer lenguaje con el que muchos novatos entran al mundo de la programación. Puede usarse tanto para mostrar simples cuadros de alerta en el navegador como para controlar robots mediante nodebot o nodruino. Los desarrolladores capaces de escribir código JavaScript con una estructura clara y un rendimiento eficiente se han convertido hoy en día en los más solicitados del mercado laboral.

En este artículo, compartiré algunos consejos, trucos y mejores prácticas de JavaScript que, salvo unas pocas excepciones, son aplicables tanto al motor de JavaScript del navegador como al intérprete de JavaScript del lado del servidor.

El código de ejemplo de este artículo ha sido probado en la última versión de Google Chrome 30 (V8 3.20.17.15).

1. Al asignar valor a una variable por primera vez, asegúrate de usarvarpalabra clave

Si una variable se asigna sin declararse, por defecto se convierte en una nueva variable global; debes evitar usar variables globales en la medida de lo posible.

2. Usa===en lugar de==

==y!=El operador convierte automáticamente los tipos de datos cuando es necesario. Pero===y!==no lo hacen; comparan tanto el valor como el tipo de datos, lo que también los hace más==y!=rápidos.

[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 y cadenas vacías tienen un resultado lógico de false

4. Usa punto y coma al final de la línea

En la práctica es mejor usar el punto y coma; si olvidas escribirlo, no pasa nada, la mayoría de las veces el intérprete de JavaScript lo añade automáticamente. Para saber por qué usar el punto y coma, consulta el artículoLa verdad sobre el punto y coma en JavaScript。

5. Usa constructores de objetos

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

6. Ten cuidado al usartypeof、instanceofycontructor

  • typeof: operador unario de JavaScript, utilizado para devolver el tipo primitivo de una variable en forma de cadena; ten en cuenta quetypeof nulltambién devuelveobject, la mayoría de los tipos de objeto (Array, Date, etc.) también devuelvenobject
  • contructor: propiedad interna del prototipo, que se puede sobrescribir con código
  • instanceof: operador de JavaScript que busca en la cadena de prototipos en el constructor; si lo encuentra, devuelvetrue, de lo contrario devuelvefalse
var arr = ["a", "b", "c"];
typeof arr;   // 返回 "object" 
arr instanceof Array // true
arr.constructor();  //[]

7. Usa funciones autoejecutables

La función se ejecuta automáticamente justo después de crearse; normalmente se denomina función anónima autoejecutable (Self-Invoked Anonymous Function) o expresión de función invocada directamente (Immediately Invoked Function Expression). El formato es el siguiente:

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

8. Obtén un miembro aleatorio de un array

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

9. Obtén un número aleatorio dentro de un rango especificado

Esta función es especialmente útil al generar datos falsos para pruebas, como por ejemplo salarios dentro de un rango especificado.

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

10. Genera un array de números de 0 a un valor especificado

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

11. Genera una cadena alfanumérica aleatoria

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

12. Mezcla el orden de un array de números

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]  */

Aquí se usa la función de ordenación de arrays integrada en JavaScript; un mejor método es implementarlo con código específico (como el algoritmo de Fisher-Yates). Puedes consultar la discusión en StackOverflowesta discusión。

13. Eliminar espacios en blanco de una cadena

Lenguajes como Java, C# y PHP han implementado funciones específicas para eliminar espacios en una cadena, pero JavaScript no; con el siguiente código se puede añadir alStringobjeto función unotrimfunción:

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

Los nuevos motores de JavaScript ya tienentrim()la implementación nativa de.

14. Anexar arrays entre sí

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 objeto en un array

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

16. Verificar si es un número

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

17. Verificar si es un array

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

Pero sitoString()el método ha sido sobrescrito, no funcionará. También puedes usar el siguiente método:

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

Si no se utilizan frames en el navegador, también se puede usarinstanceof, pero si el contexto es demasiado complejo, también puede fallar.

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. Obtener el valor máximo y mínimo de un array

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. Vaciar un array

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

20. No elimines directamente del arraydeleteoremoveelementos

Si se usa directamente sobre elementos del arraydelete, en realidad no se elimina, solo se establece el elemento comoundefined. La eliminación de elementos de un array debe usarsplice。

Evita:

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] */

En cambio:

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]

Para eliminar propiedades de un objeto se puede usardelete。

21. Usalengthla propiedad para truncar un array

En el ejemplo anterior se usólengthla propiedad para vaciar el array; igualmente se puede usar para truncarlo:

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

Al mismo tiempo, si selengthaumenta la propiedad, el valor de longitud del array aumentará y se utilizaránundefinedcomo relleno para los nuevos elementos.lengthes una propiedad escribible.

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

22. Usa operadores lógicos AND/OR en condiciones

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();

El operador lógico OR también se puede usar para establecer valores por defecto, como los valores por defecto de parámetros de función.

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

23. Haz quemap()los métodos de función recorran los datos

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

24. Conserva un número específico de decimales

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

Ten en cuenta quetoFixec()devuelve una cadena, no un número.

25. Problemas con el cálculo de punto flotante

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

¿Por qué? Porque 0.1+0.2 es igual a 0.30000000000000004. Los números de JavaScript se construyen siguiendo el estándar IEEE 754; internamente se representan como números de coma flotante de 64 bits. Puedes consultarCómo se codifican los números en JavaScript.

Se puede resolver usandotoFixed()ytoPrecision()para resolver este problema.

26. Verifica las propiedades de un objeto con el bucle for-in

El siguiente uso puede evitar que la iteración entre en las propiedades del prototipo del objeto.

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

27. El operador coma

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. Almacena temporalmente variables para cálculo y consulta

En los selectores de jQuery, se puede almacenar temporalmente todo el elemento DOM.

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

29. Comprueba de antemano losisFinite()parámetros pasados

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

30. Evita usar números negativos como índices en arrays

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

Ten cuidado al pasarspliceel parámetro índice no debe ser negativo; cuando es negativo, se eliminarán elementos desde el final del array.

31. Usa JSON para serializar y deserializar

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. No useseval()o constructores de funciones

eval()y el constructor de funciones (Functionconsturctor) tiene una sobrecarga grande; cada vez que se llama, el motor de JavaScript tiene que convertir el código fuente en código ejecutable.

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

33. Evita usarwith()

usarwith()puede agregar variables al ámbito global; por lo tanto, si hay otras variables con el mismo nombre, por un lado es fácil confundirse y por otro lado su valor también será sobrescrito.

34. No uses for-in en arrays

Evita:

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

En cambio:

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

Otro beneficio es que,iylenlas dos variables están enforla primera declaración del bucle; ambas solo se inicializan una vez, esto es más rápido que la siguiente forma de escritura:

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

35. Al pasar asetInterval()ysetTimeout()usa una función en lugar de una cadena

Si se pasa asetTimeout()ysetInterval()una cadena, la convertirán de manera similar aevalla conversión mediante eval; esto ciertamente será más lento, por lo tanto no uses:

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

En cambio usa:

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

36. Usaswitch/caseen lugar de un montón deif/else

Cuando haya más de dos ramas en la decisión, usaswitch/casees más rápido, y también más elegante, más propicio para la organización del código; por supuesto, si hay más de 10 ramas, no usesswitch/case.

37. Enswitch/caseusa rangos numéricos

De hecho,switch/caselas condiciones decasecase también se pueden escribir así:

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. Usa objetos como prototipo de objetos

Así, puedes pasar un objeto dado como parámetro para crear un nuevo objeto que lo use como prototipo:

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

39. Funciones de conversión de campos HTML

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

40. No uses try-catch-finally dentro de bucles

En try-catch-finally, la parte catch, al ejecutarse, asigna la excepción a una variable; esta variable se construye como una nueva variable dentro del ámbito de ejecución.

Evita:

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  
    } 
}

En su lugar, debes:

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. Al usar XMLHttpRequests, asegúrate de establecer un tiempo de espera (timeout)

Cuando una XMLHttpRequest se ejecuta y no hay respuesta durante mucho tiempo (como problemas de red), se debe cancelar la conexión; esto se puede hacer mediantesetTimeout()para completar esta tarea:

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();

También ten en cuenta que no debes realizar múltiples peticiones XMLHttpRequests al mismo tiempo.

42. Maneja el tiempo de espera de WebSocket

Normalmente, después de que se crea una conexión WebSocket, si no hay actividad en 30 segundos, el servidor aplicará un tiempo de espera a la conexión; el firewall también puede aplicar un tiempo de espera a las conexiones sin actividad en un período determinado.

Para evitar que esto ocurra, se puede enviar un mensaje vacío al servidor a intervalos regulares. Esto se puede lograr con las siguientes dos funciones: una para mantener la conexión activa y otra específicamente para finalizar ese estado.

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()Las funciones se pueden colocar en elonOpen()final del método,cancelKeepAlive()y la otra en elonClose()final del método.

43. Ten siempre en cuenta que los operadores nativos son más rápidos que las llamadas a funciones; usa VanillaJS

Por ejemplo, generalmente no hagas esto:

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

Puedes reemplazarlo así:

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

44. Presta atención a la estructura del código durante el desarrollo; revisa y comprime el código JavaScript antes de publicar

No olvides usar una herramienta de formateo de código al escribir código. Usa JSLint (una herramienta de verificación de sintaxis) y comprime el código antes de publicar (por ejemplo, con JSMin). Nota: hoy en día para la compresión de código se suele recomendar UglifyJS (https://github.com/mishoo/UglifyJS2)

45. JavaScript es vasto y profundo; aquí tienes algunos buenos recursos de aprendizaje

  • Recursos de Code Academy: http://www.codecademy.com/tracks/javascript
  • Escrito por Marjin HaverbekexEloquent JavaScript:http://eloquentjavascript.net/
  • Escrito por John ResigAdvanced JavaScript:http://ejohn.org/apps/learn/

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