𝗣𝗹𝗮𝗶𝗻𝗩𝗮𝗻𝗶𝗹𝗹𝗮𝗝𝗦𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝗡𝗮𝗺𝗲𝘀
让我们直接解决问题:文件大小。此处列出的所有其他答案都会使您的代码膨胀到极致。我向您介绍,为了获得最佳性能,代码的可读性,大规模项目管理,许多代码编辑器中的语法提示以及通过最小化来减小代码大小,这是进行枚举的正确方法:下划线表示变量。
wvwvwvwvwvwvwvwvwvwvwvwvww
如上图和以下示例所示,这是五个简单的入门步骤:
- 确定枚举组的名称。想一想可以描述枚举目的或至少枚举条目的名词。例如,代表用户可以选择的颜色的一组枚举可能比COLORS更好地命名为COLORCHOICES。
- 确定组中的枚举是互斥的还是独立的。如果是互斥的,则以开头的每个枚举变量名
ENUM_
。如果是独立的或并排使用,请使用INDEX_
。
- 对于每个条目,创建一个新的局部变量,其名称以
ENUM_
或开头INDEX_
,然后是组的名称,然后是下划线,然后是属性的唯一友好名称。
- 添加
ENUMLENGTH_
,ENUMLEN_
,INDEXLENGTH_
,或者INDEXLEN_
(无论是LEN_
或LENGTH_
在最后是个人喜好)枚举变量。您应该在代码中尽可能使用此变量,以确保向枚举添加额外的条目并递增此值不会破坏您的代码。
- 给每一个连续变量枚举值一个超过最后,从0开始。有迹象表明,说这个页面的评论
0
不应该被用来作为一个枚举值,因为0 == null
,0 == false
,0 == ""
,和其他JS疯狂。我谨向您指出,为避免此问题并同时提高性能,请始终使用===
并且不要让==
代码出现在typeof
(ex typeof X == "string"
)之外,除非带有(ex )。在使用的所有年份中===
,我从来没有遇到过使用0作为枚举值的问题。如果您仍然很笨拙,那么在许多情况下1
可以用作ENUM_
枚举(而不是INDEX_
枚举)的起始值,而不会降低性能。
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
}
这是我记得何时使用INDEX_
和何时使用的方法ENUM_
:
// Precondition: var arr = []; //
arr[INDEX_] = ENUM_;
但是,ENUM_
在某些情况下,例如当计算每个项目的出现次数时,它可能适合作为索引。
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]
});
观察一下,在上面的代码中,添加一种新的宠物真的很容易:您只需要在其后追加一个新条目ENUM_PET_RAT
并进行相应的更新即可ENUMLEN_PET
。在其他枚举系统中添加新条目可能会更加困难且容易出错。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
𝗘𝘅𝘁𝗲𝗻𝗱𝗨𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝘀𝗪𝗶𝘁𝗵𝗔𝗱𝗱𝗶𝘁𝗶𝗼𝗻
此外,此枚举语法允许清晰简洁的类扩展,如下所示。要扩展类,请LEN_
在父类的条目中添加一个递增的数字。然后,用自己的LEN_
条目完成子类,以便将来可以进一步扩展子类。
(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);
(长度:2,450字节)
有人可能会说这比其他解决方案不太实用:它占用了很多空间,需要花费很长时间来编写,并且没有使用糖语法。如果他们不缩减代码,那么这些人将是正确的。但是,没有理性的人会在最终产品中留下未缩小的代码。对于这种缩小,Closure Compiler是我尚未找到的最好的。在线访问可以在这里找到。Closure编译器能够获取所有这些枚举数据并将其内联,从而使您的Javascript变得超级精简,并且能够快速运行超级精简。因此,使用Closure Compiler进行压缩。观察一下。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
Closure编译器能够通过推理执行一些非常令人难以置信的优化,而这些推理远远超出了其他Javascript缩小器的能力。Closure Compiler能够内联设置为固定值的基本变量。Closure Compiler还能够基于这些内联值进行推断,并消除if语句和循环中未使用的块。
'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);
(长度:605字节)
Closure Compiler奖励您更聪明地编码和组织代码,因为尽管许多压缩工具会以较小的文件大小来惩罚有组织的代码,但是Closure Compiler能够筛选出所有的整洁度,如果您使用技巧也能输出较小的文件大小像变量名枚举一样。在这种情况下,这就是编码的圣杯:一种既可以以较小的最小尺寸协助您的代码,又可以通过训练更好的编程习惯来协助您的思想的工具。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
𝗦𝗶𝘇𝗲
现在,让我们看看没有任何这些枚举的等效文件将有多大。
不使用枚举的源(长度:1,973字节(比枚举代码短477字节!))
最小尺寸,不使用枚举(长度:843字节(比枚举代码长 238字节))
可以看出,没有枚举,源代码会更短,但代价是较大的缩小代码。我对你一无所知; 但是我确定我不会将源代码包含到最终产品中。因此,这种枚举形式非常优越,因为它导致较小的缩小文件大小。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
𝗖𝗼𝗼𝗽𝗲𝗿𝗮𝘁𝗶𝘃𝗲🤝𝗕𝘂𝗴𝗙𝗶𝘅𝗶𝗻𝗴
这种枚举形式的另一个优点是,它可用于轻松管理大型项目,而无需牺牲最小化的代码大小。在与许多其他人一起从事大型项目时,最好使用创建代码的人明确标记和标记变量名称,这样可以快速识别出代码的原始创建者以进行协作的错误修复,这可能是有益的。
// 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
}
𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲
此外,这种枚举形式在最小化后也要快得多。在普通的命名属性中,浏览器必须使用哈希图来查找该属性在对象上的位置。尽管JIT编译器在对象上智能地缓存了该位置,但是由于特殊情况(例如从对象中删除较低的属性),仍然存在巨大的开销。
但是,使用连续的非稀疏整数索引的PACKED_ELEMENTS数组,由于已经指定了内部数组中值的索引,因此浏览器可以跳过很多开销。是的,根据ECMAScript标准,所有属性都应视为字符串。尽管如此,ECMAScript标准的这一方面在性能上还是极具误导性,因为所有浏览器都对数组中的数字索引进行了特殊的优化。
/// Hashmaps are slow, even with JIT juice
var ref = {};
ref.count = 10;
ref.value = "foobar";
将上面的代码与下面的代码进行比较。
/// Arrays, however, are always lightning fast
const INDEX_REFERENCE_COUNT = 0;
const INDEX_REFERENCE_VALUE = 1;
const INDEXLENGTH_REFERENCE = 2;
var ref = [];
ref[INDEX_REFERENCE_COUNT] = 10;
ref[INDEX_REFERENCE_VALUE] = "foobar";
一个人可能会反对带有枚举的代码,而枚举似乎要比带有普通对象的代码长得多,但看起来可能是骗人的。重要的是要记住,使用史诗级的Closure Compiler时,源代码的大小与输出的大小不成比例。观察一下。
/// Hashmaps are slow, even with JIT juice
var a={count:10,value:"foobar"};
没有枚举的最小化代码在上面,而带有枚举的最小化代码在下面。
/// Arrays, however, are always lightning fast
var a=[10,"foobar"];
上面的示例说明,除了具有卓越的性能之外,枚举的代码还导致较小的缩小文件大小。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴
此外,这种一个人的个人在上面的樱桃是用这种形式与沿枚举CodeMirror在Javascript模式文本编辑器。CodeMirror的Javascript语法突出显示模式突出显示当前作用域中的局部变量。这样,您就可以正确输入变量名,从而立即知道,因为如果以前使用var
关键字声明了变量名,则变量名会变成特殊的颜色(默认为青色)。即使您不使用CodeMirror,也至少浏览器会抛出一个有用的信息。[variable name] is not defined
使用错误的枚举名称执行代码时发生异常。同样,JavaScript工具(例如JSLint和Closure Compiler)在告诉您何时键入枚举变量名称时非常吵闹。CodeMirror,浏览器和各种Javascript工具一起使调试这种枚举形式变得非常简单而且非常容易。
const ENUM_COLORENUM_RED = 0,
ENUM_COLORENUM_GREEN = 1,
ENUM_COLORENUM_BLUE = 2,
ENUMLEN_COLORENUM = 3;
var currentColor = ENUM_COLORENUM_GREEN;
if(currentColor === ENUM_COLORENUM_RED) {
// whatever
}
if(currentColor === ENUM_COLORENUM_DNE) {
// whatever
}
在以上代码段中,由于ENUM_COLORENUM_DNE
不存在错误,您收到了警报。
wvwwww wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvw
☑☑
我认为可以肯定地说,这种枚举方法确实是最好的方法,不仅是为了减小代码大小,而且还是性能,调试和协作。
阅读了有用的问题后,我感谢作者通过在问题框中单击左上角的向上箭头,将时间花在写作上。每个答案框也具有这些向上箭头之一。
0
用作枚举数。除非用于未设置的内容。false || undefined || null || 0 || "" || '' || NaN
使用进行比较时,JS将所有值视为相同的值==
。