𝗩𝗮𝗻𝗶𝗹𝗹𝗮𝗝𝗦 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲
Hãy để chúng tôi cắt thẳng vào vấn đề: kích thước tập tin. Tất cả các câu trả lời khác được liệt kê ở đây nở mã của bạn đến cực độ. Tôi trình bày với bạn rằng để có hiệu suất tốt nhất có thể, khả năng đọc mã, quản lý dự án quy mô lớn, gợi ý cú pháp trong nhiều trình soạn thảo mã và giảm kích thước mã bằng cách rút gọn, đây là cách chính xác để thực hiện liệt kê: biến ký hiệu gạch dưới.
www
Như đã trình bày trong biểu đồ trên và ví dụ bên dưới, đây là năm bước dễ dàng để bắt đầu:
- Xác định tên cho nhóm liệt kê. Hãy nghĩ về một danh từ có thể mô tả mục đích của bảng liệt kê hoặc ít nhất là các mục trong bảng liệt kê. Ví dụ: một nhóm các bảng liệt kê màu sắc mà người dùng có thể lựa chọn có thể được đặt tên tốt hơn MÀU SẮC hơn MÀU SẮC.
- Quyết định xem các liệt kê trong nhóm là loại trừ lẫn nhau hay độc lập. Nếu loại trừ lẫn nhau, hãy bắt đầu mỗi tên biến được liệt kê với
ENUM_
. Nếu độc lập hoặc cạnh nhau, sử dụng INDEX_
.
- Đối với mỗi mục nhập, hãy tạo một biến cục bộ mới có tên bắt đầu bằng
ENUM_
hoặc INDEX_
sau đó là tên của nhóm, sau đó là dấu gạch dưới, sau đó là tên thân thiện duy nhất cho thuộc tính
- Thêm một
ENUMLENGTH_
, ENUMLEN_
, INDEXLENGTH_
, hoặc INDEXLEN_
(cho dù LEN_
hoặc LENGTH_
là sở thích cá nhân) biến được liệt kê vào cuối. Bạn nên sử dụng biến này bất cứ nơi nào có thể trong mã của bạn để đảm bảo rằng việc thêm một mục nhập vào bảng liệt kê và tăng giá trị này sẽ không phá vỡ mã của bạn.
- Cung cấp cho mỗi biến liệt kê liên tiếp một giá trị một nhiều hơn trước, bắt đầu từ 0. Có ý kiến trên trang này mà nói
0
không nên được sử dụng như một giá trị được liệt kê bởi vì 0 == null
, 0 == false
, 0 == ""
, và sự điên loạn JS khác. Tôi gửi cho bạn rằng, để tránh vấn đề này và tăng hiệu suất cùng một lúc, luôn luôn sử dụng ===
và không bao giờ để ==
xuất hiện trong mã của bạn ngoại trừ với typeof
(ví dụ typeof X == "string"
). Trong tất cả các năm sử dụng ===
, tôi chưa bao giờ gặp vấn đề với việc sử dụng 0 làm giá trị liệt kê. Nếu bạn vẫn còn vuông vức, thì 1
có thể được sử dụng làm giá trị bắt đầu trong ENUM_
bảng liệt kê (nhưng không phải trong INDEX_
bảng liệt kê) mà không bị phạt hiệu suất trong nhiều trường hợp.
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
}
Đây là cách tôi nhớ khi nào nên sử dụng INDEX_
và khi nào nên sử dụng ENUM_
:
// Precondition: var arr = []; //
arr[INDEX_] = ENUM_;
Tuy nhiên, ENUM_
trong một số trường hợp, có thể thích hợp làm chỉ số như khi đếm số lần xuất hiện của từng mục.
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]
});
Quan sát rằng, trong đoạn mã trên, thật dễ dàng để thêm một loại thú cưng mới: bạn sẽ phải nối thêm một mục mới sau đó ENUM_PET_RAT
và cập nhật ENUMLEN_PET
tương ứng. Có thể khó khăn hơn và có lỗi khi thêm một mục mới trong các hệ thống liệt kê khác.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
𝗨𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝘀 𝗪𝗶𝘁𝗵
Ngoài ra, cú pháp liệt kê này cho phép mở rộng lớp rõ ràng và súc tích như được thấy dưới đây. Để mở rộng một lớp, thêm một số tăng vào LEN_
mục nhập của lớp cha. Sau đó, kết thúc lớp con với LEN_
mục nhập riêng để lớp con có thể được mở rộng hơn nữa trong tương lai.
(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);
(Độ dài: 2.450 byte)
Một số người có thể nói rằng điều này ít thực tế hơn các giải pháp khác: nó mất rất nhiều không gian, mất nhiều thời gian để viết và nó không được phủ bằng cú pháp đường. Những người đó sẽ đúng nếu họ không giảm thiểu mã của họ. Tuy nhiên, không có người hợp lý sẽ để lại mã chưa được tối ưu hóa trong sản phẩm cuối cùng. Đối với việc thu nhỏ này, Trình biên dịch đóng cửa là trình biên dịch tốt nhất mà tôi chưa tìm thấy. Truy cập trực tuyến có thể được tìm thấy ở đây . Trình biên dịch đóng có thể lấy tất cả dữ liệu liệt kê này và nội tuyến nó, làm cho Javascript của bạn trở nên siêu nhỏ và chạy siêu nhanh. Do đó, Minify với Trình biên dịch đóng. Quan sát.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
Trình biên dịch đóng có thể thực hiện một số tối ưu hóa đáng kinh ngạc thông qua các suy luận vượt quá khả năng của bất kỳ công cụ khai thác Javascript nào khác. Trình biên dịch đóng cửa có thể đặt các biến nguyên thủy nội tuyến thành một giá trị cố định. Trình biên dịch đóng cửa cũng có thể thực hiện các suy luận dựa trên các giá trị được nội tuyến này và loại bỏ các khối không được sử dụng trong câu lệnh if và vòng lặp.
'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);
(Độ dài: 605 byte)
Trình biên dịch đóng cửa thưởng cho bạn mã hóa thông minh hơn và tổ chức mã của bạn tốt bởi vì, trong khi nhiều công cụ khai thác trừng phạt mã có tổ chức với kích thước tệp được rút gọn lớn hơn, thì Trình biên dịch đóng gói có thể sàng lọc tất cả sự sạch sẽ và tỉnh táo của bạn để tạo ra kích thước tệp thậm chí nhỏ hơn nếu bạn sử dụng các thủ thuật như liệt kê tên biến. Điều đó, trong suy nghĩ này, là chén thánh của mã hóa: một công cụ vừa hỗ trợ mã của bạn với kích thước nhỏ hơn vừa phải và hỗ trợ tâm trí của bạn bằng cách rèn luyện thói quen lập trình tốt hơn.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
𝗖𝗼𝗱𝗲
Bây giờ, chúng ta hãy xem tệp tương đương sẽ lớn như thế nào nếu không có bất kỳ bảng liệt kê nào.
Nguồn không sử dụng liệt kê (độ dài: 1.973 byte (ngắn hơn 477 byte so với mã liệt kê!))
Được rút gọn mà không sử dụng liệt kê (độ dài: 843 byte ( dài hơn 238 byte so với mã liệt kê ))
Như đã thấy, không có bảng liệt kê, mã nguồn ngắn hơn với chi phí của mã rút gọn lớn hơn. Tôi không biết gì về bạn; nhưng tôi biết chắc chắn rằng tôi không kết hợp mã nguồn vào sản phẩm cuối cùng. Do đó, hình thức liệt kê này vượt trội hơn nhiều so với kết quả là kích thước tệp được rút gọn nhỏ hơn.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
🤝 𝗕𝘂𝗴
Một ưu điểm khác về hình thức liệt kê này là nó có thể được sử dụng để dễ dàng quản lý các dự án quy mô lớn mà không phải hy sinh kích thước mã được rút gọn. Khi làm việc trong một dự án lớn với nhiều người khác, có thể có ích khi đánh dấu và gắn nhãn rõ ràng tên biến với người đã tạo mã để người tạo mã gốc có thể nhanh chóng được xác định để sửa lỗi cộng tác.
// 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
}
𝗦𝘂𝗽𝗲𝗿𝗶𝗼𝗿 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲
Hơn nữa, hình thức liệt kê này cũng nhanh hơn nhiều sau khi thu nhỏ. Trong các thuộc tính được đặt tên bình thường, trình duyệt phải sử dụng các hashtag để tìm kiếm vị trí của thuộc tính trên đối tượng. Mặc dù trình biên dịch JIT lưu trữ thông minh vị trí này trên đối tượng một cách thông minh, nhưng vẫn có chi phí rất lớn do các trường hợp đặc biệt như xóa một thuộc tính thấp hơn khỏi đối tượng.
Nhưng, với các mảng PACKED_ELEMENTS được lập chỉ mục số nguyên không thưa thớt liên tục , trình duyệt có thể bỏ qua phần lớn chi phí đó vì chỉ mục của giá trị trong mảng bên trong đã được chỉ định. Có, theo tiêu chuẩn ECMAScript, tất cả các thuộc tính được coi là được coi là chuỗi. Tuy nhiên, khía cạnh này của tiêu chuẩn ECMAScript rất sai lệch về hiệu suất vì tất cả các trình duyệt có tối ưu hóa đặc biệt cho các chỉ mục số trong mảng.
/// Hashmaps are slow, even with JIT juice
var ref = {};
ref.count = 10;
ref.value = "foobar";
So sánh mã trên với mã dưới đây.
/// 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";
Người ta có thể phản đối mã với các liệt kê dường như dài hơn nhiều so với mã với các đối tượng thông thường, nhưng ngoại hình có thể bị đánh lừa. Điều quan trọng cần nhớ là kích thước mã nguồn không tỷ lệ với kích thước đầu ra khi sử dụng Trình biên dịch đóng cửa sử thi. Quan sát.
/// Hashmaps are slow, even with JIT juice
var a={count:10,value:"foobar"};
Mã rút gọn không có bảng liệt kê ở trên và mã được rút gọn với bảng liệt kê ở dưới.
/// Arrays, however, are always lightning fast
var a=[10,"foobar"];
Ví dụ trên chứng minh rằng, ngoài việc có hiệu suất vượt trội, mã được liệt kê còn dẫn đến kích thước tệp được thu nhỏ hơn.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
𝗘𝗮𝘀𝘆 𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴
Hơn nữa, anh đào cá nhân trên đỉnh này đang sử dụng hình thức liệt kê này cùng với trình soạn thảo văn bản CodeMirror ở chế độ Javascript. Chế độ tô sáng cú pháp Javascript của CodeMirror làm nổi bật các biến cục bộ trong phạm vi hiện tại. Bằng cách đó, bạn biết ngay lập tức khi bạn nhập tên biến chính xác bởi vì nếu tên biến được khai báo trước đó bằng var
từ khóa, thì tên biến sẽ chuyển sang màu đặc biệt (màu lục lam theo mặc định). Ngay cả khi bạn không sử dụng CodeMirror, thì ít nhất trình duyệt cũng sẽ hữu ích[variable name] is not defined
ngoại lệ khi thực thi mã với tên liệt kê sai. Ngoài ra, các công cụ JavaScript như JSLint và Trình biên dịch đóng cửa rất lớn về việc cho bạn biết khi bạn nhập sai tên biến liệt kê. CodeMirror, trình duyệt và các công cụ Javascript khác nhau kết hợp lại giúp việc gỡ lỗi hình thức liệt kê này rất đơn giản và thực sự dễ dàng.
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
}
Trong đoạn trích trên, bạn đã được thông báo lỗi vì ENUM_COLORENUM_DNE
không tồn tại.
wvvvvvvvvvv v tuần năm tuần năm năm nay năm nay năm tuần năm năm nay năm nay năm tuần năm năm ngày thứ năm mùa thứ năm mùa thứ năm mùa năm mùa năm tuần thứ năm thứ năm mùa chiều sáng sóng sáng thứ năm tuần thứ năm thứ năm thứ năm thứ năm năm nay năm nay năm nay năm nay
𝗖𝗼𝗻𝗰𝗹𝘂𝘀𝗶𝗼𝗻 ☑
Tôi nghĩ thật an toàn khi nói rằng phương pháp liệt kê này thực sự là cách tốt nhất để đi không chỉ cho kích thước mã được rút gọn, mà còn cho hiệu suất, gỡ lỗi và cộng tác.
Sau khi đọc một câu hỏi hữu ích, tôi cảm ơn tác giả đã đổ thời gian vào bài viết của họ bằng cách nhấp vào mũi tên trên cùng bên trái trong hộp câu hỏi. Mỗi hộp trả lời cũng có một trong những mũi tên hướng lên.
0
như một số liệt kê. Trừ khi nó được sử dụng cho một cái gì đó chưa được thiết lập. JS coifalse || undefined || null || 0 || "" || '' || NaN
tất cả là cùng một giá trị khi so sánh sử dụng==
.