Cómo escribir código JS personalizable y mantenible
Esta vez le mostraré cómo escribir código JS personalizable y mantenible, y cuáles son las precauciones para escribir código JS personalizable y mantenible. El siguiente es un caso práctico, echemos un vistazo.
1.1 Formato
Acerca de los niveles de sangría: no quiero iniciar un debate entre “Tab o Espacio” y “2 o 4 o 6 u 8 Espacios”, está bien este tema Después de horas de debate, la sangría incluso está relacionada con los valores de los programadores. Sólo necesitas recordar los siguientes tres puntos:
El código debe tener sangría y mantenerse alineado.
No mezcles Tabulador y Espacio en el mismo proyecto.
Mantener la coherencia con el estilo del equipo.
Acerca del punto y coma final: basándose en el mecanismo de inserción automática de punto y coma (ASI) del analizador, el código JS puede funcionar normalmente incluso si se omite el punto y coma. ASI busca automáticamente lugares en el código donde se debería usar un punto y coma pero no existe y lo inserta. En la mayoría de los escenarios, ASI insertará punto y coma correctamente sin causar errores, pero las reglas de inserción de punto y coma de ASI son muy complicadas y difíciles de recordar, por lo que recomiendo no omitir punto y coma. La mayoría de las guías de estilo (excepto el estilo estándar de JavaScript) recomiendan no omitir el punto y coma.
Acerca de la longitud de línea: La mayoría de los lenguajes y guías de estilo de codificación JS especifican que la longitud de una línea es de 80 caracteres. Este valor proviene del límite máximo de caracteres de una sola línea en los editores de texto hace mucho tiempo. , es decir, en el editor Una sola línea solo puede mostrar hasta 80 caracteres. Las líneas que superen los 80 caracteres estarán ajustadas u ocultas, lo que no queremos. También tiendo a limitar la longitud de la línea a 80 caracteres.
Acerca del ajuste de línea: cuando la longitud de una línea alcanza el límite máximo de caracteres para una sola línea, debe dividir manualmente una línea en dos líneas. Por lo general, ajustaremos la línea después del operador y la siguiente línea agregará dos niveles de sangría (personalmente creo que una sangría está bien, pero no ninguna sangría). Por ejemplo:
callFunc(document, element, window, 'test', 100, true);
En este ejemplo, la coma es un operador y debe usarse como en el anterior cola de línea. Esta posición de salto de línea es muy importante porque el mecanismo ASI insertará un punto y coma al final de la línea en algunos escenarios. Al colocar siempre un operador al final de la línea, ASI no insertará punto y coma por iniciativa propia, evitando así errores. Hay una excepción a esta regla: al asignar un valor a una variable, la posición de la segunda línea debe estar alineada con la posición del operador de asignación. Por ejemplo:
var resultado = algo + otra cosa + otra cosa + otra cosa +
otra cosa más En este código, la variable otra cosa más y el algo al principio de la línea están alineados a la izquierda; garantiza la legibilidad del código y puede ver claramente el contexto del texto roto de un vistazo.
Acerca de las líneas en blanco: En las especificaciones de programación, las líneas en blanco son un aspecto que muchas veces se ignora. En términos generales, el código debería verse como una serie de párrafos legibles, en lugar de un gran bloque de texto continuo. A veces, la semántica de un fragmento de código no está relacionada con otro fragmento de código. En este caso, se debe utilizar una línea en blanco para separarlos para garantizar que el código semánticamente relacionado se muestre junto. En términos generales, se recomienda agregar líneas en blanco en los siguientes escenarios:
Entre métodos.
Entre variables locales y la primera declaración del método.
Antes de un comentario de varias líneas o de una sola línea.
Inserte líneas en blanco entre fragmentos lógicos dentro de los métodos para mejorar la legibilidad.
1.2 Denominación
La denominación se divide en cuatro categorías: variables, constantes, funciones y constructores: las variables y funciones utilizan nombres en mayúsculas y minúsculas (la primera letra está en minúscula) y constructores. use nomenclatura en mayúsculas grandes (letra mayúscula), use todas las letras mayúsculas para las constantes y separe las palabras con guiones bajos.
let myAge; // Variables: nomenclatura CamelCase const PAGE_SIZE; // Constantes: todas en mayúsculas, use guiones bajos para separar palabras function getAge() {} // Funciones ordinarias: nomenclatura CamelCase person() { } //Constructor: denominación CamelCase
Para distinguir variables y funciones, los nombres de las variables deben tener el prefijo de nombres y los nombres de las funciones deben tener el prefijo de verbos (los nombres de los constructores suelen ser sustantivos). Mire el siguiente ejemplo:
let count = 10; // Goodlet getCount = 10; // Malo, parece la función function getName() {} // Goodfunction theName() {} // Malo, parece variable Los nombres no son solo una ciencia, sino también una tecnología, pero en términos generales, la longitud del nombre debe ser lo más corta posible y capturar los puntos principales. Intente reflejar el tipo de datos del valor en el nombre de la variable. Por ejemplo, los nombres recuento, longitud y tamaño indican que el tipo de datos es un número, mientras que los nombres nombre, título y mensaje indican que el tipo de datos es una cadena. Pero las variables nombradas con caracteres únicos como i, j y k generalmente se usan en bucles. El uso de estos nombres que reflejen el tipo de datos puede hacer que su código sea más fácil de leer para otros y para usted mismo.
Evite el uso de nombres sin sentido como foo, bar y tmp. Para nombrar funciones y métodos, la primera palabra debe ser un verbo. A continuación se muestran algunas convenciones comunes para el uso de verbos:
Significado del verbo
La función can devuelve un valor booleano
tiene una función que devuelve un valor booleano
esta función devuelve un valor booleano
la función get devuelve un valor no booleano
la función set se utiliza para guardar a Valores
1.3 Literales
JS contiene algunos tipos de valores primitivos: cadenas, números, valores booleanos, nulos e indefinidos. También incluye literales de objetos y literales de matriz. Entre ellos, solo los valores booleanos se explican por sí mismos, y otros tipos requieren más o menos pensar en cómo se pueden expresar con mayor precisión.
Acerca de las cadenas: las cadenas pueden usar comillas dobles o comillas simples. Las diferentes especificaciones de JS tienen diferentes recomendaciones, pero recuerde no mezclar comillas simples y comillas dobles en un proyecto.
Acerca de los números: tenga en cuenta dos sugerencias: primero, para evitar ambigüedades, no omita los números antes o después del punto decimal; segundo, la mayoría de los desarrolladores no están familiarizados con el formato octal y tienen pocos utilizados, por lo que la mejor práctica es desactivar los literales octales en su código.
// Método de escritura decimal no recomendado: precio de alquiler sin parte decimal = 10.;// Método de escritura decimal no recomendado: precio de alquiler sin parte entera = .1;// Método de escritura no recomendado: escritura octal método Ha quedado obsoleto let num = 010;
Acerca de nulo: nulo es un valor especial, pero a menudo lo malinterpretamos y lo confundimos con indefinido. Null debe usarse en los siguientes escenarios.
Se utiliza para inicializar una variable, que puede asignarse a un objeto.
Se utiliza para comparar con una variable inicializada, que puede ser o no un objeto.
Cuando se espera que el parámetro de la función sea un objeto, se pasa como parámetro.
Cuando se espera que el valor de retorno de la función sea un objeto, se utiliza como valor de retorno y se pasa.
También existen los siguientes escenarios en los que no se debe utilizar null.
No utilice nulo para detectar si se pasa un parámetro.
No utilice nulo para detectar una variable no inicializada.
La mejor manera de entender null es como un marcador de posición para un objeto. Esta regla no se menciona en ninguna especificación de programación convencional, pero es crucial para el mantenimiento global.
Acerca de indefinido: indefinido es un valor especial y a menudo lo confundimos con nulo. Una de las cosas confusas es que null == undefinido da como resultado verdadero. Sin embargo, estos dos valores tienen usos diferentes. Aquellas variables que no han sido inicializadas tienen un valor inicial, es decir, indefinido, lo que significa que la variable está esperando que se le asigne un valor. Por ejemplo:
let person; // Mala escritura console.log(person === undefinido); // verdadero Aunque este código funciona bien, recomiendo evitar el uso de indefinido en el código. Este valor a menudo se confunde con el operador typeof, que devuelve "indefinido". De hecho, el comportamiento de typeof también es muy desconcertante, porque independientemente de si el valor es una variable indefinida o una variable no declarada, el resultado de la operación typeof es "indefinido". Por ejemplo:
// foo no está declarado let person; console.log(typeof person); // "indefinido" console.log(typeof foo); // En el código "indefinido", persona y foo hará que typeof devuelva "indefinido", incluso si el comportamiento de person y foo son muy diferentes en otros escenarios (usar foo en una declaración informará un error, pero usar person no informará un error).
Al prohibir el uso del valor especial indefinido, efectivamente garantiza que typeof devolverá "indefinido" solo en un caso: cuando se declara la variable. Si utiliza una variable que puede (o no) asignarse a un objeto, asígnela a nulo.
// Buena práctica let person = null; console.log(person === null); // true asignar el valor inicial de una variable a null indica la intención de esta variable, y es probable que sea así. eventualmente se le asignará un valor como objeto. El operador typeof devuelve "objeto" cuando opera con el tipo nulo, para que pueda distinguirse de indefinido.
Acerca de los literales de objetos y los literales de matrices: utilice la sintaxis literal directamente para crear objetos y matrices, y evite utilizar los constructores de objetos y matrices para crear objetos y matrices.
1.4 Comentarios
Los comentarios son el componente más común del código. Son otra forma de documentación y son lo último en lo que los programadores están dispuestos a dedicar tiempo a escribir. Sin embargo, los comentarios son una parte muy importante del mantenimiento general de su código. JS admite dos tipos de comentarios: comentarios de una sola línea y comentarios de varias líneas.
A muchas personas les gusta escribir un espacio después de la doble barra para compensar el texto del comentario (te recomiendo encarecidamente que lo hagas). Hay tres formas de utilizar comentarios de una sola línea:
Se utiliza una línea exclusiva de comentarios para explicar la siguiente línea de código. Esta línea de comentario siempre va precedida por una línea en blanco y el nivel de sangría sigue siendo el mismo que el de la siguiente línea de código.
Un comentario al final de una línea de código. Debe haber al menos una sangría entre el final del código y el comentario. Los comentarios (incluida la sección de código anterior) no deben exceder el límite máximo de caracteres; de ser así, el comentario se colocará encima de la línea de código actual.
Una gran sección de código comentada (muchos editores pueden comentar varias líneas de código en lotes).
Los comentarios de una sola línea no deben aparecer como comentarios consecutivos de varias líneas a menos que comente una sección grande de código. Utilice comentarios de varias líneas sólo cuando necesite comentar una sección larga de texto.
Aunque los comentarios de varias líneas también se pueden utilizar para comentar líneas individuales, sigo recomendando utilizar comentarios de varias líneas solo cuando necesite utilizar comentarios de varias líneas.
Los comentarios de varias líneas se utilizan generalmente en los siguientes escenarios:
Comentarios al comienzo de módulos, clases y funciones
Es necesario utilizar comentarios de varias líneas
Le recomiendo encarecidamente que utilice el estilo Java. Los comentarios de varias líneas se ven muy bonitos y muchos editores admiten la generación automática. Consulte el siguiente ejemplo:
/**
* Estilo Java comentarios, preste atención a la diferencia entre * y comentarios. Hay un espacio entre
*, y también hay un espacio a la izquierda de *.
* Incluso puedes agregar algunos parámetros @ para explicar algo.
* Por ejemplo:
*
* @autor autor
* @param Persona objeto
* / Cuándo agregar comentarios es un tema a menudo debatido entre los programadores. Una pauta general es que se deben agregar comentarios cuando el código no sea lo suficientemente claro y no se deben agregar comentarios cuando el código sea claro. Con base en este principio, recomiendo agregar comentarios en las siguientes situaciones:
Código difícil de entender: el código difícil de entender generalmente debe comentarse. Dependiendo del propósito del código, puede utilizar comentarios de una sola línea, comentarios de varias líneas o una combinación de ambos. La clave es hacer que este código sea más fácil de leer para otros.
Código que puede confundirse con errores: Por ejemplo, este código while(el && (el = el.next)) {}. En el desarrollo en equipo, siempre habrá algunos desarrolladores bien intencionados que encontrarán errores de código de otras personas al editar el código y los corregirán de inmediato. A veces, este código no es la fuente del error, por lo que "arreglar" el error a menudo creará otros errores, por lo que este cambio debe ser rastreable. Cuando escribe código que otros desarrolladores pueden considerar incorrecto, debe agregar comentarios.
Hack de funciones del navegador: todos los que han escrito front-end lo saben. A veces hay que escribir código ineficiente, poco elegante y francamente sucio para que los navegadores de baja versión funcionen correctamente.
1.5 Declaraciones y Expresiones
Con respecto a la alineación de llaves, existen dos estilos principales de alineación de llaves. El primer estilo es colocar la llave izquierda al final de la primera línea de código en la declaración de bloque. Este estilo se hereda de Java. El segundo estilo es colocar la llave izquierda en la línea que sigue a la primera línea. declaración de bloque. Este estilo El estilo se hizo popular en C# porque Visual Studio impuso esta alineación. Actualmente no existe ninguna especificación de programación JS convencional que recomiende este estilo. La guía de estilo de Google JS prohíbe explícitamente este uso para evitar que se inserten automáticamente puntos y comas incorrectos. Personalmente, también recomiendo utilizar el formato de alineación de la primera llave.
// El primer estilo de alineación de llaves si (condición) {
}// El segundo estilo de alineación de llaves si (condición)
{ p>
}Acerca del espaciado de declaraciones de bloque: existen los siguientes tres estilos. La mayoría de los estándares de código recomiendan el segundo estilo:
// El primer estilo if(condition){ p>
. doSomething();
}// El segundo estilo si (condición) {
doSomething();
}// El segundo estilo si (condición) {
doSomething();
}// Tres estilos if ( condition ) {
doSomething();
} Respecto a Declaración de cambio, muchas especificaciones del código JS no proporcionan disposiciones detalladas para esto. Una es que en el trabajo real También encontrará que hay menos escenarios de uso. Porque solo usará switch cuando haya muchas condiciones para juzgar (las condiciones cortas usan declaraciones if directamente), pero los programadores expertos generalmente usan consultas de tablas de objetos para resolver este problema cuando se enfrentan a muchas condiciones de juicio.
Consulte el siguiente código de estilo recomendado:
switch (condición) { case 'cond1': case 'cond2':
doCond1(); case 'cond3':
doCond3(); break; default:
doDefault();
} Se recomienda seguir el siguiente estilo:
Corchetes condicionales después del cambio Se requiere un espacio antes y después;
La declaración de caso debe tener una sangría de un nivel en relación con la declaración de cambio
Se permite que varias declaraciones de caso utilicen una declaración de procesamiento;
Si no hay un código de ejecución predeterminado, no es necesario agregarlo.
Acerca de with: los motores JS y las herramientas de compresión no pueden optimizar el código with con declaraciones porque no pueden adivinar la correcta significado del código. En modo estricto, la declaración with está explícitamente prohibida y, si se utiliza, se informará un error de sintaxis. Esto indica que el comité ECMAScript está convencido de que with no debería seguir utilizándose. También recomiendo encarecidamente evitar la declaración with.
Acerca de los bucles for: hay dos tipos de bucles for. Uno es el bucle for tradicional, que JS hereda de C y Java y se utiliza principalmente para atravesar miembros de matrices; en Loop, se utiliza para recorrer las propiedades de un objeto.
Para los bucles for, recomiendo evitar el uso de continuar tanto como sea posible, pero no hay razón para prohibir completamente su uso. Su uso debe determinarse en función de la legibilidad del código.
El bucle for-in se utiliza para recorrer las propiedades del objeto. Sin definir ninguna condición de control, el bucle recorrerá metódicamente cada propiedad del objeto y devolverá el nombre de la propiedad en lugar del valor. Un problema con el bucle for-in es que no solo atraviesa las propiedades de instancia del objeto, sino que también atraviesa las propiedades heredadas del prototipo. Al iterar sobre las propiedades de un objeto personalizado, a menudo termina con resultados inesperados. Por este motivo, es mejor utilizar el método hasOwnProperty() para filtrar las propiedades de instancia para bucles for-in. También te recomiendo que hagas esto, a menos que realmente quieras recorrer la cadena de prototipos del objeto, en cuyo caso deberías agregar un comentario.
// Contiene un recorrido de la cadena del prototipo for (let prop in obj) { console.log(`key: ${prop}; value: ${obj[prop]}`);
}for (let prop in obj) { if (obj.hasOwnProperty(prop)) { console.log(`key: ${prop}; valor: ${obj[prop]}`);
}
} Con respecto al bucle for-in, hay otra cosa a tener en cuenta, es decir, el bucle for-in se utiliza para atravesar objetos. Un error común es usar un bucle for-in para iterar sobre los miembros de la matriz. Es posible que el resultado no sea el que desea (lo que obtiene es un subíndice de la matriz). Debe usar el bucle for-of de ES6 para iterar sobre la matriz.
let arr = ['a', 'b', 'c'];for (let i in arr) { console.log(i); // 0, 1, 2}for (let). v of arr) { console.log(v); // 'a', 'b', 'c'}1.6 Declaración de variables
Sabemos que las variables declaradas por var en JS tienen promoción de variables. Se producirán errores inesperados cuando los estudiantes que no estén familiarizados con él escriban código.
Por ejemplo:
func función () { var resultado = 10 + resultado; var valor = 10; devolver resultado; // devolver NaN}// en realidad se interpreta como función func () { var resultado; valor ;
resultado = 10 + resultado;
valor = 10; devolver resultado;
}En algunos escenarios, los desarrolladores a menudo omiten la promoción variable, la declaración for es uno de los ejemplos comunes (porque no había alcance a nivel de bloque antes de ES5):
func func (arr) { for (var i = 0, len = arr.length; i < len; i += 1) {}
}//realmente interpretado como función func (arr) { var i, len; for (i = 0, len = arr.length; i < len; i + = 1 ) {}
}La declaración de variable por adelantado significa: definir variables en cualquier lugar dentro de la función es exactamente lo mismo que definir variables en la parte superior de la función. Por lo tanto, un estilo popular es colocar todas las declaraciones de variables en la parte superior de la función en lugar de esparcirlas por todas partes. En resumen, la lógica del código escrita en este estilo es muy similar a la costumbre del motor JS de analizar este código. También recomiendo que siempre definas variables locales como la primera declaración dentro de una función.
función func (arr) { var i, len; var valor = 10; var resultado = valor + 10; len = arr.length; i < len; i += 1 ) { console.log(arr[i]);
}
} Por supuesto, si tienes la oportunidad de usar ES6, te recomiendo encarecidamente que abandones var por completo y use let y const para definir variables. Créame, definitivamente vale la pena abandonar var. Deje que y const proporcionen un alcance a nivel de bloque, que es más seguro y confiable que var, y el comportamiento es más predecible.
1.7 Declaración y llamada de funciones
Al igual que las declaraciones de variables, el motor JS también promoverá las declaraciones de funciones. Por lo tanto, las llamadas a funciones pueden aparecer antes de las declaraciones de funciones en el código. Sin embargo, recomendamos siempre declarar primero las funciones JS y luego usarlas. Además, las declaraciones de funciones no deberían aparecer dentro de los bloques de declaraciones. Por ejemplo, este código no se ejecutará como pretendíamos:
// Mala escritura if (condition) { function func () {
alert("¡Hola! "); p>
}
} else { function func() {
alerta("¡Yo!");
}
}Los resultados de este código que se ejecuta en diferentes navegadores también son diferentes. Independientemente de cómo se evalúe la condición, la mayoría de los navegadores utilizan automáticamente la segunda declaración. Firefox selecciona la declaración de función adecuada según el resultado del cálculo de la condición. Este escenario es un área gris con ECMAScript y debe evitarse siempre que sea posible. Las declaraciones de funciones deben usarse fuera de las declaraciones condicionales. Este patrón también está explícitamente prohibido por la guía de estilo JS de Google.
Generalmente, el estilo recomendado para escribir llamadas a funciones es que no haya espacios entre el nombre de la función y el corchete izquierdo. Esto se hace para diferenciarlo de las declaraciones en bloque.
// Buen método de escritura callFunc(params);// Mal método de escritura, parece una declaración de bloque callFunc (params);// Declaración de bloque utilizada para comparar while (condición) {}
1.8 Función invocada inmediatamente
IIFE (Expresión de función invocada inmediatamente) significa una expresión de función invocada inmediatamente, es decir, la función se llama inmediatamente cuando se declara la función. Rara vez se usa en ES6 debido al mecanismo del módulo, y el objetivo principal de IIFE es simular el alcance del aislamiento del módulo. Aquí hay algunos métodos de escritura IIFE recomendados:
// Mal método de escritura: hará que la gente piense erróneamente que se asigna una función anónima a esta variable var value = function () { return { msg: 'Hola'
};
}();// Para que IIFE sea visible de un vistazo, puede envolver la función con un par de paréntesis// Buen método de escritura var value = ( function () { return { msg: 'Hola'
};
}());// Buena forma de escribir valor var = (function () { return { msg : ' Hola'
};
})();1.9 Modo estricto
Si estás escribiendo código ES5, se recomienda utilizar siempre el modo estricto . No se recomienda utilizar el modo estricto global, ya que puede provocar errores en el código antiguo. Se recomienda utilizar el modo estricto a nivel de función o utilizar el modo estricto en IIFE.
1.10 Igualdad
En cuanto al mecanismo de conversión de conversión de JS, tenemos que admitir que es realmente muy complicado y difícil de recordarlo todo (principalmente por pereza). Así que te recomiendo que, en cualquier caso, uses === y !== al hacer comparaciones de igualdad.
1.11 eval
La ejecución dinámica de cadenas JS no es una buena idea. En las siguientes situaciones, JS se puede ejecutar dinámicamente. Le sugiero que evite hacer esto a menos que sea competente. en JS y saber lo que estás haciendo.
eval("alert('malo')"); const func = new Function("alert malo('malo')");
setTimeout("alert('malo')" ')", 1000);
setInterval("alert('bad')", 1000);1.12 Tipo de embalaje original
Comprenda el embalaje y unboxing de JS, valores originales No hay Propiedades y métodos. Cuando llamamos a un método de cadena, el motor JS encuadrará automáticamente el valor original en un objeto y luego llamará al método de este objeto. Pero esto no significa que deba utilizar tipos de empaquetado primitivos para crear los valores primitivos correspondientes, porque las ideas de los desarrolladores a menudo saltan entre objetos y valores primitivos, lo que aumentará la probabilidad de errores, lo que confundirá a los desarrolladores. No hay ninguna razón para que usted mismo cree manualmente estos objetos.
//Auto-boxing const name = 'Nicholas';console.log(name.toUpperCase());//Buen método de escritura const name = 'Nicholas';const Author = true;const count = 10;//Mala forma de escribir const name = new String('Nicholas');const Author = new String(true);const count = new Number(10);1.13 Herramientas
En desarrollo por parte del equipo, Para mantener un estilo unificado, la herramienta Lint es esencial. Porque aunque todos entienden que deben cumplir con un estilo de programación unificado, siempre inadvertidamente violan la guía de estilo al escribir código (después de todo, la gente comete errores).
Aquí le recomiendo que utilice la herramienta ESLint para verificar el estilo del código. No necesita reescribir completamente las reglas de configuración. Puede heredar los estándares de codificación JS líderes en la industria para ajustar su equipo. Recomiendo heredar de la Guía de estilo de JavaScript de Airbnb. Por supuesto, también puede heredar la configuración recomendada oficialmente o el estilo de codificación JS de Google. De hecho, en términos de estilo de codificación, la mayoría de las reglas son iguales, pero en algunas. Detalles simplemente inconsistentes.
Por supuesto, si realmente eres demasiado vago, entonces entiéndelo