El estilo que elija para su proyecto debe ser el criterio más alto. Coloque como una descripción en su proyecto y vinculélo a este documento como garantía de la consistencia, legibilidad y mantenimiento del estilo del código.
1. En blanco
1. Nunca mezcle espacios y pestañas.
2. Inicie un proyecto, seleccione Soft Indent (Space) o Tab (como método de sangría) antes de escribir el código y úselo como el criterio más alto.
a). Para la legibilidad, siempre recomiendo diseñar la sangría de ancho de 2 letras en sus ediciones: esto es equivalente a dos espacios o dos espacios en lugar de una pestaña.
3. Si su editor lo admite, siempre active la configuración "Mostrar caracteres invisibles". Los beneficios son:
a). Asegurar la consistencia
b). Retire los espacios al final de la línea
do). Retire los espacios en blanco
d). La presentación y la comparación son más legibles
2. Embellece la gramática
A. aparatos ortopédicos, aparatos ortopédicos, rupturas de línea
La copia del código es la siguiente:
// if/else/for/while/try generalmente tiene aparatos ortopédicos, aparatos ortopédicos y múltiples líneas
// Esto ayuda a legible
// 2.A.1.1
// Ejemplo de sintaxis difícil
if (condición) dosomething ();
mientras (condición) iterando ++;
para (var i = 0; i <100; i ++) some OterativeFn ();
// 2.A.1.1
// Use espacios para mejorar la legibilidad
if (condición) {
// Declaración
}
while (condición) {
// Declaración
}
para (var i = 0; i <100; i ++) {
// Declaración
}
// Mejor práctica:
var i,
longitud = 100;
para (i = 0; i <longitud; i ++) {
// Declaración
}
// o...
var i = 0,
longitud = 100;
para (; i <longitud; i ++) {
// Declaración
}
var apto;
para (prota en objeto) {
// Declaración
}
if (true) {
// Declaración
} demás {
// Declaración
}
B. Asignar, declaración, función (funciones nombradas, expresiones de funciones, funciones de constructor)
La copia del código es la siguiente:
// 2.B.1.1
// variable
var foo = "bar",
num = 1,
undef;
// Identificación literal:
varilla var = [],
objeto = {};
// 2.B.1.2
// usar solo un `var` dentro de un alcance (función) ayuda a mejorar la legibilidad
// y hacer que su lista de declaraciones sea ordenada (también le guarda algunas tipificación de teclado)
// no es bueno
var foo = "";
var bar = "";
var qux;
// bien
var foo = "",
bar = "",
quux;
// o..
var // Comentarios sobre estas variables
foo = "",
bar = "",
quux;
// 2.B.1.3
// La instrucción `var` siempre debe estar en la parte superior de cada alcance (función)
// también es adecuado para constantes de Ecmascript 6
// no es bueno
función foo () {
// Hay una declaración antes de la variable
bar bar = "",
qux;
}
// bien
función foo () {
bar bar = "",
qux;
// Todas las declaraciones son después de la variable
}
// 2.B.2.1
// Declaración de funciones con nombre
función foo (arg1, argn) {
}
// Cómo usar
foo (arg1, argn);
// 2.B.2.2
// Declaración de funciones con nombre
Función Square (número) {
número de devolución * número;
}
// Cómo usar
cuadrado (10);
// Estilo de pase de continuación muy antinatural
Función Square (número, devolución de llamada) {
devolución de llamada (número * número);
}
cuadrado (10, función (cuadrado) {
// contenido de devolución de llamada
});
// 2.B.2.3
// Expresión de funciones
var cuadro = function (número) {
// devuelve contenido valioso y relevante
número de devolución * número;
};
// Expresión de funciones con identificador
// Este formulario preferido tiene funciones adicionales que le permiten llamarse a sí misma
// y hay un identificador en la pila
var factorial = función factorial (número) {
if (número <2) {
regresar 1;
}
número de retorno * factorial (número-1);
};
// 2.B.2.4
// Declaración del constructor
Función Foobar (Opciones) {
this.options = options;
}
// Cómo usar
var foobar = new Foobar ({a: "alfa"});
foobar.options;
// {a: "alfa"}
C. Excepción, detalles
La copia del código es la siguiente:
// 2.C.1.1
// Funciones con devoluciones de llamada
foo (function () {
// NOTA: No hay espacios en los soportes y la `función 'de la primera llamada de función
});
// La función acepta 'Array` como argumento, sin espacios
foo (["alfa", "beta"]);
// 2.C.1.2
// La función acepta `objeto` como argumento, sin espacios
foo ({
A: "alfa",
B: "beta"
});
// La función acepta la `string` literal como argumento, sin espacios
foo ("bar");
// No hay espacios dentro de los soportes utilizados para agrupar
if (! ("foo" en obj)) {
}
D. La consistencia siempre gana
En las secciones 2.A-2.C, el espacio en blanco se propone como un método de recomendación, basado en un propósito simple y superior: unificación. Vale la pena señalar que las preferencias de formato, como el "espacio interno en blanco" deben ser opcionales, pero solo debe haber un tipo de código fuente de todo el proyecto.
La copia del código es la siguiente:
// 2.d.1.1
if (condición) {
// Declaración
}
while (condición) {
// Declaración
}
para (var i = 0; i <100; i ++) {
// Declaración
}
if (true) {
// Declaración
} demás {
// Declaración
}
E. Citas
No importa si elige cotizaciones simples o dobles, no hacen una diferencia de análisis en JavaScript. Lo que absolutamente necesita ser ordenado es la consistencia. Nunca mezcle dos citas en el mismo proyecto, elija una y manténgala consistente.
F. Fin de línea y línea vacía
Dejar en blanco romperá la diferencia y los cambios de uso son ilegibles. Considere incluir un gancho precometido que elimine automáticamente los espacios al final de la línea y las líneas en blanco.
3. Detección de tipo (de las directrices de estilo de JQuery Core)
A. Tipo directo (tipo real, tipo real)
Cadena:
La copia del código es la siguiente:
typeOf variable === "cadena"
Número:
La copia del código es la siguiente:
typeOf variable === "número"
Booleano:
La copia del código es la siguiente:
typeOf variable === "booleano"
Objeto:
La copia del código es la siguiente:
typeOf variable === "objeto"
Formación:
La copia del código es la siguiente:
Array.IsArray (ArraylikeObject)
(Si es posible)
Nodo:
La copia del código es la siguiente:
Elem.nodetype === 1
nulo:
La copia del código es la siguiente:
variable === nulo
nulo o indefinido:
La copia del código es la siguiente:
variable == nulo
indefinido:
Variables globales:
La copia del código es la siguiente:
typeOf variable === "indefinido"
Variables locales:
La copia del código es la siguiente:
variable === indefinido
propiedad:
La copia del código es la siguiente:
Object.prop === Undefinado
Object.HasownProperty (Prop)
"Propiedad" en el objeto
B. Tipo de conversión (tipo coerciado, tipos coaccionados)
Considere el significado de lo siguiente ...
Dado html:
La copia del código es la siguiente:
<input type = "text" id = "foo-input" value = "1">
// 3.B.1.1
// `foo` se le ha asignado un valor de` 0`, tipo `número`
var foo = 0;
// typeOf foo;
// "número"
...
// En el código posterior, debe actualizar `foo` y asignar un nuevo valor obtenido en el elemento de entrada
foo = document.getElementById ("foo-input"). valor;
// Si prueba `typeof foo` ahora, el resultado será` string '
// Esto significa que tiene una lógica similar a esta al detectar `foo` en la instrucción if:
if (foo === 1) {
IMPORTANTETASK ();
}
// `IMPORTANTECT ()` nunca se ejecutará, incluso si 'foo` tiene un valor de "1"
// 3.B.1.2
// Puede usar hábilmente el operador +/- Unario para lanzar el tipo para resolver el problema:
foo = +document.getElementById ("foo-input"). valor;
// ^ + El operador unario convierte el objeto de operación a su derecha en `número '
// typeOf foo;
// "número"
if (foo === 1) {
IMPORTANTETASK ();
}
// `IMPORTANTECT ()` se llamará
Aquí hay algunos ejemplos para el casting:
La copia del código es la siguiente:
// 3.B.2.1
número var = 1,
String = "1",
bool = falso;
número;
// 1
número + "";
// "1"
cadena;
// "1"
+cadena;
// 1
+String ++;
// 1
cadena;
// 2
bool;
// FALSO
+bool;
// 0
bool + "";
// "FALSO"
// 3.B.2.2
número var = 1,
String = "1",
bool = verdadero;
cadena === Número;
// FALSO
cadena === Número + "";
// verdadero
+String === Número;
// verdadero
bool === número;
// FALSO
+bool === número;
// verdadero
bool === cadena;
// FALSO
bool === !! cadena;
// verdadero
// 3.B.2.3
var array = ["a", "b", "c"];
!! ~ array.indexof ("a");
// verdadero
!! ~ array.indexof ("b");
// verdadero
!! ~ array.indexof ("c");
// verdadero
!! ~ array.indexof ("d");
// FALSO
// vale la pena señalar que lo anterior son todos "innecesarios inteligentes"
// Use un esquema claro para comparar los valores devueltos
// por ejemplo índice de:
if (array.indexof ("a")> = 0) {
// ...
}
// 3.B.2.3
var num = 2.5;
parseint (num, 10);
// equivalente a ...
~~ num;
num >> 0;
num >>> 0;
// Los resultados son todos 2
// Tenga siempre en cuenta, los valores negativos se tratarán de manera diferente ...
var neg = -2.5;
parseint (neg, 10);
// equivalente a ...
~~ neg;
neg >> 0;
// Los resultados son todos -2
// pero...
neg >>> 0;
// El resultado es 4294967294
4. Operaciones comparativas
La copia del código es la siguiente:
// 4.1.1
// Al juzgar si una matriz tiene una longitud, en relación con el uso de esto:
if (array.length> 0) ...
// ... Para determinar la autenticidad, use esto:
if (array.length) ...
// 4.1.2
// Al juzgar si una matriz está vacía, en relación con el uso de esto:
if (array.length === 0) ...
// ... Para determinar la autenticidad, use esto:
if (! Array.length) ...
// 4.1.3
// Al juzgar si una cadena está vacía, en relación con el uso de esto:
if (string! == "") ...
// ... Para determinar la autenticidad, use esto:
if (cadena) ...
// 4.1.4
// Al juzgar que una cadena está vacía, en relación con el uso de esto:
if (string === "") ...
// ... Para determinar la autenticidad, use esto:
if (! String) ...
// 4.1.5
// Al juzgar que una referencia es verdadera, en relación con el uso de esto:
if (foo === verdadero) ...
// ... juzga tal como piensas, disfruta de los beneficios de las características integradas:
if (foo) ...
// 4.1.6
// Al juzgar que una referencia es falsa, en relación con el uso de esto:
if (foo === falso) ...
// ... Conviértalo a verdadero usando una marca de exclamación
if (! foo) ...
// ... Cabe señalar que esto coincidirá con 0, "", nulo, indefinido, nan
// Si usted _Must_ es un tipo booleano falso, use esto:
if (foo === falso) ...
// 4.1.7
// Si desea calcular una referencia, puede ser nulo o indefinido, pero no es falso "o 0,
// en relación con el uso de esto:
if (foo === null || foo === Undefined) ...
// ... Disfrute de los beneficios de == Casting de tipo, como este:
if (foo == nulo) ...
// Recuerda que usar == hará que `null` coincida con` null` y 'indefinido'
// pero no `falso`," o 0
nulo == Undefinado
Siempre juzga los mejores y más precisos valores, lo anterior es una guía en lugar de un dogma.
La copia del código es la siguiente:
// 4.2.1
// Instrucciones para las operaciones de conversión y comparación de tipo
// primera vez `===`, `==` seguido (a menos que se necesite una comparación de tipo suelta)
// `===` no siempre hace la conversión de tipo, lo que significa:
"1" === 1;
// FALSO
// `==` Convierte el tipo, lo que significa:
"1" == 1;
// verdadero
// 4.2.2
// booleano, verdadero y falso
// booleano:
verdadero, falso
// real:
"foo", 1
// Seudo:
"", 0, nulo, indefinido, nan, nulo 0
5. Estilo práctico
La copia del código es la siguiente:
// 5.1.1
// Un módulo práctico
(función (global) {
var módulo = (function () {
var data = "secreto";
devolver {
// Este es un valor booleano
Bool: verdadero,
// una cadena
cadena: "una cadena",
// una matriz
Matriz: [1, 2, 3, 4],
// un objeto
objeto: {
Lang: "En-US"
},
getData: function () {
// Obtener el valor de `Data`
devolver datos;
},
setData: function (valor) {
// devuelve el valor asignado de `data`
return (data = valor);
}
};
}) ();
// otros aparecerán aquí
// Convierte tu módulo en un objeto global
global.module = módulo;
})( este );
// 5.2.1
// una función de construcción práctica
(función (global) {
función ctor (foo) {
this.foo = foo;
devolver esto;
}
Ctor.prototype.getfoo = function () {
devolver esto.foo;
};
Ctor.prototype.setfoo = function (val) {
return (this.foo = val);
};
// No use `New` para llamar a la función de compilación, puede hacer esto:
var ctor = function (foo) {
devolver nuevo ctor (foo);
};
// Convertir nuestra función de compilación en un objeto global
global.ctor = ctor;
})( este );
6. Naming
R. No eres un compilador/compresor humano, así que trata de transformarte en uno.
El siguiente código es un ejemplo de un nombre muy malo:
La copia del código es la siguiente:
// 6.A.1.1
// Código de ejemplo de nombre de nombre malo
función q (s) {
return document.QueryselectorAlt (s);
}
var i, a = [], els = q ("#foo");
para (i = 0; i <els.length; i ++) {a.push (els [i]);}
No hay duda de que ha escrito dicho código, espero que no aparezca nuevamente a partir de hoy.
Aquí hay un código con la misma lógica, pero con un nombre más robusto y apt (y una estructura legible):
La copia del código es la siguiente:
// 6.A.2.1
// Código de ejemplo mejorado con nombre
Function Query (Selector) {
return document.QueryselectorAll (selector);
}
var idx = 0,
elementos = [],
Matches = Query ("#foo"),
Longitud = Matches.length;
para (; idx <longitud; idx ++) {
Elements.push (coincide [idx]);
}
Algunos consejos de nombres adicionales:
La copia del código es la siguiente:
// 6.A.3.1
// String llamado
`Dog 'es una cuerda
// 6.A.3.2
// matrices de nombre
`['perros']` es una matriz que contiene la cuerda de perro
// 6.A.3.3
// Nombre de funciones, objetos, instancias, etc.
camlcase; Declaraciones de función y var
// 6.A.3.4
// Nombre al constructor, prototipo, etc.
Pascalcase; Función de construcción
// 6.A.3.5
// nombre expresiones regulares
rdesc = //;
// 6.A.3.6
// de la guía de estilo de biblioteca de cierre de Google
functionNamesLikethis;
VariAblenameslikethis;
Constructornameslikethis;
Enumnameslikethis;
MethodNamesLikethis;
Symbolic_constants_like_this;
B. enfrenta esto
Además de usar llamadas y aplicar conocidas, .Bind (esto) o un funcionalmente equivalente siempre se prefiere. Cree una Declaración deFuncia Límite para llamadas posteriores, utilizando alias cuando no hay una opción mejor.
La copia del código es la siguiente:
// 6.B.1
Dispositivo de función (OPTS) {
this.Value = null;
// Crear una nueva transmisión asincrónica, esto se llamará continuamente
stream.read (opts.path, function (data) {
// Use la transmisión para devolver el último valor de los datos y actualizar el valor de la instancia
this.value = data;
} .bind (this));
// Controle la frecuencia de activación del evento
setInterval (function () {
// publicar un evento controlado
this.emit ("evento");
} .bind (this), opts.freq || 100);
}
// Supongamos que hemos heredado el EventEmitter;)
Cuando no se puede ejecutar, el equivalente de .Bind está disponible en la mayoría de las bibliotecas de JavaScript modernas.
La copia del código es la siguiente:
// 6.B.2
// Ejemplo: lodash/subscore, _.bind ()
Dispositivo de función (OPTS) {
this.Value = null;
stream.read (opts.path, _.bind (function (data) {
this.value = data;
}, este) );
setInterval (_. bind (function () {
this.emit ("evento");
}, esto), opts.freq || 100);
}
// Ejemplo: jQuery.proxy
Dispositivo de función (OPTS) {
this.Value = null;
stream.read (opts.path, jquery.proxy (function (data) {
this.value = data;
}, este) );
setInterval (jQuery.proxy (function () {
this.emit ("evento");
}, esto), opts.freq || 100);
}
// Ejemplo: dojo.hitch
Dispositivo de función (OPTS) {
this.Value = null;
stream.read (opts.path, dojo.hitch (this, function (data) {
this.value = data;
}));
setInterval (dojo.hitch (this, function () {
this.emit ("evento");
}), opts.freq || 100);
}
Proporcione un candidato para crear un alias para esto, con uno mismo como identificador. Es muy probable que esto tenga errores y debe evitarse tanto como sea posible.
La copia del código es la siguiente:
// 6.B.3
Dispositivo de función (OPTS) {
var self = this;
this.Value = null;
stream.read (opts.path, function (data) {
self.value = data;
});
setInterval (function () {
self.emit ("evento");
}, opts.freq || 100);
}
C. Use Thisarg
Varios métodos prototipos en ES 5.1 tienen una etiqueta especial de thesarg integrada, úsela tanto como sea posible
La copia del código es la siguiente:
// 6.C.1
var obj;
obj = {f: "foo", b: "bar", q: "qux"};
Object.Keys (obj) .ForEach (function (Key) {
// | esto | Ahora es `obj`
console.log (esta [clave]);
}, obj); // <- El último parámetro es `thantarg`
// Imprimir ...
// "foo"
// "bar"
// "qux"
ThatErg se puede usar en Array.Prototype.Every, Array.Prototype.ForEach, Array.Prototype.Meome, Array.Prototype.map y Array.Prototype.Filter.
7. Misc
Las ideas e ideas que esta parte explicará no son dogmáticas. En cambio, se recomienda más a tener curiosidad sobre las prácticas existentes para tratar de proporcionar una mejor solución para completar las tareas generales de programación de JavaScript.
A. Evite usar el interruptor. El rastreo de métodos modernos se inclinará en la lista negra con las expresiones de conmutación.
Parece que tanto Firefox como Chrome han realizado mejoras significativas para cambiar las declaraciones. http://jsperf.com/switch-vs-object-literal-vs-module
Vale la pena señalar que la mejora se puede ver aquí: https://github.com/rwldrn/idiomatic.js/issues/13
La copia del código es la siguiente:
// 7.A.1.1
// Ejemplo de instrucción de cambio
Switch (foo) {
Caso "alfa":
alfa();
romper;
Caso "beta":
beta();
romper;
por defecto:
// Rama predeterminada
romper;
}
// 7.A.1.2
// Un método que puede admitir la combinación y reutilización es usar un objeto para almacenar "casos".
// Use una función para hacer delegación:
Casos var, delegador;
// El valor de retorno es solo para explicación
casos = {
alfa: function () {
// Declaración
// un valor de retorno
return ["alfa", argumentos.length];
},
beta: function () {
// Declaración
// un valor de retorno
return ["beta", argumentos.length];
},
_default: functer () {
// Declaración
// un valor de retorno
return ["predeterminado", argumentos.length];
}
};
delegator = function () {
var args, clave, delegado;
// Convertir `argumento 'en una matriz
args = [] .slice.call (argumentos);
// extrae el último valor del `argumento '
clave = args.hift ();
// llame a la rama predeterminada
delegado = casos._default;
// delegar el método desde el objeto
if (cass.hasownproperty (key)) {
delegado = casos [clave];
}
// El alcance de Arg se puede establecer en un valor específico,
// En este caso, | NULL | esta bien
return delegate.apply (nulo, args);
};
// 7.A.1.3
// Use la API en 7.A.1.2:
delegador ("alfa", 1, 2, 3, 4, 5);
// ["alfa", 5]
// Por supuesto, el valor de la clave 'Case` se puede cambiar fácilmente a cualquier valor
var caseKey, SomeuserInput;
// ¿Hay alguna entrada posible de algún formulario?
SomeuserInput = 9;
if (SomeUsUserInput> 10) {
CaseKey = "alfa";
} demás {
CaseKey = "beta";
}
// o...
CaseKey = SomeuserInput> 10? "alfa": "beta";
// Entonces...
delegador (CaseKey, SomeuserInput);
// ["beta", 1]
// Por supuesto, esto se puede hacer ...
delegator ();
// ["predeterminado", 0]
B. Valores de devolución de antemano para mejorar la legibilidad del código sin mucha diferencia de rendimiento
La copia del código es la siguiente:
// 7.B.1.1
// no es bueno:
función returnlate (foo) {
var ret;
if (foo) {
ret = "foo";
} demás {
ret = "quux";
}
regreso de regreso;
}
// bien:
función returnearly (foo) {
if (foo) {
regresar "foo";
}
devolver "quux";
}
8. Objetos nativos y host (nota: siempre he pensado que los objetos host no deben traducirse, por lo que lo traduciré de acuerdo con el método de escritura general)
El principio más básico es:
No hagas nada estúpido, las cosas siempre mejorarán.
Para fortalecer este concepto, mira esta demostración:
"Todo está permitido: Extensión nativa" de Andrew DuPont (JSCONF2011, Portland, Oregon)
http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permited-extending-built-ins-5211542
9. Comentarios
Los comentarios de una sola línea se colocan por encima del código como la primera opción
Múltiples líneas están bien
¡Se deben evitar los comentarios al final de la línea!
El método JSDOC también es bueno, pero lleva más tiempo
10. Use un idioma solo
Independientemente del idioma que el mantenedor del programa (o equipo) estipula que se utiliza el programa, el programa debe escribirse solo en el mismo idioma.
apéndice
Coma primero
Todos los proyectos que usan este documento como una guía de estilo básico no permiten formatos de código previo al comercio a menos que el autor se especifique explícitamente o lo requiera.