Vayamos directamente al problema: el tamaño del archivo. Todas las demás respuestas enumeradas aquí inflan su código minimizado al extremo. Les presento que para la mejor reducción posible en el tamaño del código mediante la minificación, el rendimiento, la legibilidad del código, la gestión de proyectos a gran escala y las sugerencias de sintaxis en muchos editores de código, esta es la forma correcta de hacer enumeraciones: variables de notación de subrayado.
Como se demuestra en el cuadro anterior y el ejemplo a continuación, aquí hay cinco sencillos pasos para comenzar:
- Determine un nombre para el grupo de enumeración. Piense en un sustantivo que pueda describir el propósito de la enumeración o al menos las entradas en la enumeración. Por ejemplo, un grupo de enumeraciones que representan colores que puede elegir el usuario podría llamarse mejor COLORCHOICES que COLORES.
- Decidir si las enumeraciones en el grupo son mutuamente excluyentes o independientes. Si son mutuamente excluyentes, comience cada nombre de variable enumerado con
ENUM_
. Si es independiente o en paralelo, utiliceINDEX_
. - Para cada entrada, cree una nueva variable local cuyo nombre comience con
ENUM_
oINDEX_
, luego el nombre del grupo, luego un guión bajo, luego un nombre descriptivo único para la propiedad - Agrega un
ENUMLENGTH_
,ENUMLEN_
,INDEXLENGTH_
, oINDEXLEN_
(ya seaLEN_
oLENGTH_
es preferencia personal) variable enumerada al final. Debe usar esta variable siempre que sea posible en su código para asegurarse de que agregar una entrada adicional a la enumeración e incrementar este valor no romperá su código. - Asigne a cada variable enumerada sucesivamente un valor uno más que la anterior, comenzando en 0. Hay comentarios en esta página que dicen
0
no debe usarse como un valor enumerado porque0 == null
,0 == false
,0 == ""
, y otras locuras de JS. Les presento que, para evitar este problema y aumentar el rendimiento al mismo tiempo, utilice siempre===
y nunca dejes==
aparecen en su código excepto contypeof
(extypeof X == "string"
). En todos mis años de uso===
, Nunca he tenido un problema con el uso de 0 como valor de enumeración. Si todavía eres aprensivo, entonces1
podría usarse como valor inicial enENUM_
enumeraciones (pero no enINDEX_
enumeraciones) sin penalización de desempeño en muchos casos.
const ENUM_COLORENUM_RED = 0;
const ENUM_COLORENUM_GREEN = 1;
const ENUM_COLORENUM_BLUE = 2;
const ENUMLEN_COLORENUM = 3;
// later on
if(currentColor === ENUM_COLORENUM_RED) {
// whatever
}
Así es como recuerdo cuándo usar INDEX_
y cuando usar ENUM_
:
// Precondition: var arr = []; //
arr[INDEX_] = ENUM_;
Sin embargo, ENUM_
puede, en determinadas circunstancias, ser apropiado como índice, como cuando se cuentan las ocurrencias de cada elemento.
const ENUM_PET_CAT = 0,
ENUM_PET_DOG = 1,
ENUM_PET_RAT = 2,
ENUMLEN_PET = 3;
var favoritePets = [ENUM_PET_CAT, ENUM_PET_DOG, ENUM_PET_RAT,
ENUM_PET_DOG, ENUM_PET_DOG, ENUM_PET_CAT,
ENUM_PET_RAT, ENUM_PET_CAT, ENUM_PET_DOG];
var petsFrequency = [];
for (var i=0; i<ENUMLEN_PET; i=i+1|0)
petsFrequency[i] = 0;
for (var i=0, len=favoritePets.length|0, petId=0; i<len; i=i+1|0)
petsFrequency[petId = favoritePets[i]|0] = (petsFrequency[petId]|0) + 1|0;
console.log({
"cat": petsFrequency[ENUM_PET_CAT],
"dog": petsFrequency[ENUM_PET_DOG],
"rat": petsFrequency[ENUM_PET_RAT]
});
Observe que, en el código anterior, es muy fácil agregar un nuevo tipo de mascota: solo tendría que agregar una nueva entrada después de ENUM_PET_RAT
y actualizar ENUMLEN_PET
respectivamente. Podría ser más difícil y con errores agregar una nueva entrada en otros sistemas de enumeración.
Además, esta sintaxis de enumeraciones permite una extensión de clase clara y concisa como se ve a continuación. Para extender una clase, agregue un número creciente al LEN_
entrada de la clase padre. Luego, termine la subclase con su propia LEN_
entrada para que la subclase pueda extenderse más en el futuro.
(function(window){
"use strict";
var parseInt = window.parseInt;
// use INDEX_ when representing the index in an array instance
const INDEX_PIXELCOLOR_TYPE = 0, // is a ENUM_PIXELTYPE
INDEXLEN_PIXELCOLOR = 1,
INDEX_SOLIDCOLOR_R = INDEXLEN_PIXELCOLOR+0,
INDEX_SOLIDCOLOR_G = INDEXLEN_PIXELCOLOR+1,
INDEX_SOLIDCOLOR_B = INDEXLEN_PIXELCOLOR+2,
INDEXLEN_SOLIDCOLOR = INDEXLEN_PIXELCOLOR+3,
INDEX_ALPHACOLOR_R = INDEXLEN_PIXELCOLOR+0,
INDEX_ALPHACOLOR_G = INDEXLEN_PIXELCOLOR+1,
INDEX_ALPHACOLOR_B = INDEXLEN_PIXELCOLOR+2,
INDEX_ALPHACOLOR_A = INDEXLEN_PIXELCOLOR+3,
INDEXLEN_ALPHACOLOR = INDEXLEN_PIXELCOLOR+4,
// use ENUM_ when representing a mutually-exclusive species or type
ENUM_PIXELTYPE_SOLID = 0,
ENUM_PIXELTYPE_ALPHA = 1,
ENUM_PIXELTYPE_UNKNOWN = 2,
ENUMLEN_PIXELTYPE = 2;
function parseHexColor(inputString) {
var rawstr = inputString.trim().substring(1);
var result = [];
if (rawstr.length === 8) {
result[INDEX_PIXELCOLOR_TYPE] = ENUM_PIXELTYPE_ALPHA;
result[INDEX_ALPHACOLOR_R] = parseInt(rawstr.substring(0,2), 16);
result[INDEX_ALPHACOLOR_G] = parseInt(rawstr.substring(2,4), 16);
result[INDEX_ALPHACOLOR_B] = parseInt(rawstr.substring(4,6), 16);
result[INDEX_ALPHACOLOR_A] = parseInt(rawstr.substring(4,6), 16);
} else if (rawstr.length === 4) {
result[INDEX_PIXELCOLOR_TYPE] = ENUM_PIXELTYPE_ALPHA;
result[INDEX_ALPHACOLOR_R] = parseInt(rawstr[0], 16) * 0x11;
result[INDEX_ALPHACOLOR_G] = parseInt(rawstr[1], 16) * 0x11;
result[INDEX_ALPHACOLOR_B] = parseInt(rawstr[2], 16) * 0x11;
result[INDEX_ALPHACOLOR_A] = parseInt(rawstr[3], 16) * 0x11;
} else if (rawstr.length === 6) {
result[INDEX_PIXELCOLOR_TYPE] = ENUM_PIXELTYPE_SOLID;
result[INDEX_SOLIDCOLOR_R] = parseInt(rawstr.substring(0,2), 16);
result[INDEX_SOLIDCOLOR_G] = parseInt(rawstr.substring(2,4), 16);
result[INDEX_SOLIDCOLOR_B] = parseInt(rawstr.substring(4,6), 16);
} else if (rawstr.length === 3) {
result[INDEX_PIXELCOLOR_TYPE] = ENUM_PIXELTYPE_SOLID;
result[INDEX_SOLIDCOLOR_R] = parseInt(rawstr[0], 16) * 0x11;
result[INDEX_SOLIDCOLOR_G] = parseInt(rawstr[1], 16) * 0x11;
result[INDEX_SOLIDCOLOR_B] = parseInt(rawstr[2], 16) * 0x11;
} else {
result[INDEX_PIXELCOLOR_TYPE] = ENUM_PIXELTYPE_UNKNOWN;
}
return result;
}
// the red component of green
console.log(parseHexColor("#0f0")[INDEX_SOLIDCOLOR_R]);
// the alpha of transparent purple
console.log(parseHexColor("#f0f7")[INDEX_ALPHACOLOR_A]);
// the enumerated array for turquoise
console.log(parseHexColor("#40E0D0"));
})(self);
(Longitud: 2.450 bytes)
Algunos pueden decir que esto es menos práctico que otras soluciones: desperdicia toneladas de espacio, lleva mucho tiempo escribir y no está cubierto de sintaxis de azúcar. Esas personas tendrían razón si no minimizan su código. Sin embargo, ninguna persona razonable dejaría un código sin modificar en el producto final. Para esta minificación, Closure Compiler es lo mejor que tengo que encontrar. Se puede encontrar acceso en línea aquí. El compilador de cierre puede tomar todos estos datos de enumeración e incorporarlos, lo que hace que su Javascript sea súper pequeño y se ejecute súper rápido. Por lo tanto, Minify con Closure Compiler. Observar.
El compilador de cierres puede realizar algunas optimizaciones bastante increíbles a través de inferencias que están mucho más allá de las capacidades de cualquier otro minificador de Javascript. Closure Compiler es capaz de insertar variables primitivas en un valor fijo. Closure Compiler también puede hacer inferencias basadas en estos valores en línea y eliminar bloques no utilizados en sentencias if y bucles.
'use strict';(function(e){function d(a){a=a.trim().substring(1);var b=[];8===a.length?(b[0]=1,b[1]=c(a.substring(0,2),16),b[2]=c(a.substring(2,4),16),b[3]=c(a.substring(4,6),16),b[4]=c(a.substring(4,6),16)):4===a.length?(b[1]=17*c(a[0],16),b[2]=17*c(a[1],16),b[3]=17*c(a[2],16),b[4]=17*c(a[3],16)):6===a.length?(b[0]=0,b[1]=c(a.substring(0,2),16),b[2]=c(a.substring(2,4),16),b[3]=c(a.substring(4,6),16)):3===a.length?(b[0]=0,b[1]=17*c(a[0],16),b[2]=17*c(a[1],16),b[3]=17*c(a[2],16)):b[0]=2;return b}var c=
e.parseInt;console.log(d("#0f0")[1]);console.log(d("#f0f7")[4]);console.log(d("#40E0D0"))})(self);
(Longitud: 605 bytes)
Closure Compiler lo recompensa por codificar de manera más inteligente y organizar bien su código porque, mientras que muchos minificadores castigan el código organizado con un tamaño de archivo minificado más grande, Closure Compiler puede examinar toda su limpieza y cordura para generar un tamaño de archivo aún más pequeño si usa trucos como enumeraciones de nombres de variables. Eso, en esta única mente, es el santo grial de la codificación: una herramienta que ayuda a su código con un tamaño minificado más pequeño y ayuda a su mente al entrenar mejores hábitos de programación.
Ahora, veamos qué tan grande sería el archivo equivalente sin ninguna de estas enumeraciones.
Fuente sin usar enumeraciones (longitud: 1.973 bytes (477 bytes más corto que el código enumerado))
Minificado sin usar enumeraciones (longitud: 843 bytes (238 bytes más largo que el código enumerado))
Como se ve, sin enumeraciones, el código fuente es más corto a costa de un código minificado más grande. No sé sobre ti; pero estoy seguro de que no incorporo el código fuente en el producto final. Por lo tanto, esta forma de enumeraciones es muy superior en la medida en que da como resultado tamaños de archivo minificados más pequeños.
Otra ventaja de esta forma de enumeración es que se puede utilizar para gestionar fácilmente proyectos a gran escala sin sacrificar el tamaño del código minificado. Cuando se trabaja en un proyecto grande con muchas otras personas, puede ser beneficioso marcar y etiquetar explícitamente los nombres de las variables con quién creó el código para que el creador original del código pueda identificarse rápidamente para la corrección de errores en colaboración.
// JG = Jack Giffin
const ENUM_JG_COLORENUM_RED = 0,
ENUM_JG_COLORENUM_GREEN = 1,
ENUM_JG_COLORENUM_BLUE = 2,
ENUMLEN_JG_COLORENUM = 3;
// later on
if(currentColor === ENUM_JG_COLORENUM_RED) {
// whatever
}
// PL = Pepper Loftus
// BK = Bob Knight
const ENUM_PL_ARRAYTYPE_UNSORTED = 0,
ENUM_PL_ARRAYTYPE_ISSORTED = 1,
ENUM_BK_ARRAYTYPE_CHUNKED = 2, // added by Bob Knight
ENUM_JG_ARRAYTYPE_INCOMPLETE = 3, // added by jack giffin
ENUMLEN_PL_COLORENUM = 4;
// later on
if(
randomArray === ENUM_PL_ARRAYTYPE_UNSORTED ||
randomArray === ENUM_BK_ARRAYTYPE_CHUNKED
) {
// whatever
}
Además, esta forma de enumeración también es mucho más rápida después de la minificación. En las propiedades con nombre normales, el navegador tiene que usar hashmaps para buscar dónde está la propiedad en el objeto. Aunque los compiladores JIT almacenan en caché de manera inteligente esta ubicación en el objeto, todavía hay una enorme sobrecarga debido a casos especiales, como eliminar una propiedad inferior del objeto.
Pero, con índices enteros no dispersos continuos PACKED_ELEMENTS matrices, el navegador puede omitir gran parte de esa sobrecarga porque el índice del valor en la matriz interna ya está especificado. Sí, de acuerdo con el estándar ECMAScript, se supone que todas las propiedades deben tratarse como cadenas. Sin embargo, este aspecto del estándar ECMAScript es muy engañoso sobre el rendimiento porque todos los navegadores tienen optimizaciones especiales para índices numéricos en matrices.
/// Hashmaps are slow, even with JIT juice
var ref = {};
ref.count = 10;
ref.value = "foobar";
Compara el código …