Hướng dẫn javascript avoid new - javascript tránh mới

Nguồn

Mình thấy bài viết hay quá nên đọc và viết lại, chủ yếu để mình và các bạn viết code có nguyên tắc, dễ đọc, dễ hiểu, dễ bảo trì và tái sử dụng code hơn, mình có tham khảo tại :code có nguyên tắc, dễ đọc, dễ hiểu, dễ bảo trì và tái sử dụng code hơn, mình có tham khảo tại :

Show

https://github.com/hienvd/clean-code-javascript/

https://github.com/ryanmcdermott/clean-code-javascript

Giới thiệu

Hướng dẫn javascript avoid new - javascript tránh mới

Những nguyên tắc kỹ thuật phần mềm, từ cuốn sách Clean Code của Robert C. Martin's, được áp dụng cho ngôn ngữ JavaScript. Đây không phải là một hướng dẫn về cách viết code Javascript mà là hướng dẫn về cách viết các đoạn code dễ đọc hiểu, tái sử dụng và tái cấu trúc được trong Javascript.

Không phải mọi nguyên tắc ở đây phải được tuân thủ một cách nghiêm ngặt, và thậm chí chỉ có một ít trong số đó được sử dụng phổ biến. Ở đây, nó chỉ là một hướng dẫn - không hơn không kém, nhưng chúng được hệ thống hóa thông qua kinh nghiệm thu thập được qua nhiều năm của các tác giả của cuốn sách Clean Code

Ngành kỹ thuật phần mềm chỉ phát triển được hơn 50 năm, và chúng ta vẫn đang học rất nhiều. Một khi kiến trúc phần mềm trở thành phổ biến, có lẽ sau đó chúng ta sẽ có thêm nhiều luật lệ khó hơn phải tuân theo. Còn giờ đây, hãy để những hướng dẫn này như là một tiêu chuẩn để đánh giá chất lượng các đoạn code Javascript mà bạn và team của bạn tạo ra.

Biết những hướng dẫn này thôi sẽ không thể ngay lập tức làm bạn trở thành một lập trình viên phần mềm tốt hơn được, và làm việc với chúng trong nhiều năm cũng không có nghĩa bạn sẽ không gặp bất cứ sai lầm nào. Mỗi đoạn code bắt đầu như một bản thảo đầu tiên, giống như đất sét được nặn nhào và cho tới cuối cùng thì nó sẽ lộ diện hình hài. Cuối cùng, chúng ta gọt tỉa những khuyết điểm khi chúng ta xem xét lại nó cùng với các đồng nghiệp. Đừng để bản thân bạn bị đánh bại bởi những bản thảo đầu tiên, thứ mà vẫn cần phải được chỉnh sửa. Thay vào đó hãy đánh bại những dòng code.

Áp dụng

Biến

Sử dụng tên biến có nghĩa :

  • Không tốt :
// yyyymmdd là cái gì ??
const yyyymmdd = moment().format('YYYY/MM/DD');
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');

Sử dụng cùng từ vựng cho cùng loại biến :

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
  • Tốt :
getUser();

Sử dụng cùng từ vựng cho cùng loại biến :

Sử dụng các tên dễ hiểu và tìm kiếm được :buddy.jsESLint có thể giúp nhận ra các hằng chưa được đặt tên.

  • Không tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);

Sử dụng cùng từ vựng cho cùng loại biến :folder ( thư mục ) để định nghĩa những hằng số dùng chung này.

Sử dụng các tên dễ hiểu và tìm kiếm được :

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);

Sử dụng cùng từ vựng cho cùng loại biến :

Sử dụng các tên dễ hiểu và tìm kiếm được :

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});

Sử dụng cùng từ vựng cho cùng loại biến :

Sử dụng các tên dễ hiểu và tìm kiếm được :class ( lớp ), tên của Object đã nói lên điều gì đó, ít nhất nó là cái gì thì không cần phải lặp lại nó trong tên variable ( biến ).

  • Không tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
0
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
1

Sử dụng cùng từ vựng cho cùng loại biến :

  • Không tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
2
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
3

Sử dụng cùng từ vựng cho cùng loại biến :

Sử dụng các tên dễ hiểu và tìm kiếm được :

Chúng ta sẽ đọc code nhiều hơn là viết chúng. Điều quan trọng là code chúng ta viết có thể đọc được và tìm kiếm được. Việc đặt tên các biến không có ngữ nghĩa so với chương trình, chúng ta có thể sẽ làm người đọc code bị tổn thương tinh thần. Hãy làm cho các tên biến của bạn có thể tìm kiếm được. Các công cụ như buddy.js và ESLint có thể giúp nhận ra các hằng chưa được đặt tên.param ( tham số ) truyền vào 1 hàm là điều cực kì quan trọng : Nó làm cho bạn ít nhất cũng dễ nhìn hơn, dễ test hơn, Trong trường hợp có nhiều hơn 3 params có thể khiến bạn phải test hàng tấn test case khác nhau với những đối số riêng biệt.

Theo mình thì nên có 1 folder ( thư mục ) để định nghĩa những hằng số dùng chung này.param là lý tưởng cho 1 hàm, nhưng cũng có trường hợp bất khả kháng thì cũng đành chịu, tốt nhất là nên tránh truyền nhiều hơn 2 params, những trường hợp từ 3 params, chúng ta nên gộp lại.

Sử dụng những biến có thể giải thích được :param cho hàm, hàm đó sẽ càng xử lý nhiều việc hơn.

Tránh hại não người khácJavascript cho phép tạo nhiều Object một cách nhanh chóng, mà không cần nhiều class có sẵn, bạn có thể sử dụng một Object nếu bạn cần truyền nhiều param.

Trước giờ, không riêng gì trong lập trình mà mọi vẫn đề trong cuộc sống, nếu rõ ràng thì tất nhiên nó vẫn sẽ dễ hiểu hơn.hàm mong đợi những thuộc tính gì, bạn có thể sử dụng cấu trúc destructuring của ES6. Điều này có một số ưu điểm:

  1. Đừng thêm những ngữ cảnh không cần thiếthàm, những thuộc tính nào được sử dụng sẽ trở nên rõ ràng ngay lập tức.
  2. Nếu tên của class ( lớp ), tên của Object đã nói lên điều gì đó, ít nhất nó là cái gì thì không cần phải lặp lại nó trong tên variable ( biến ). cũng sao chép lại các giá trị ban đầu được chỉ định của Object param được truyền vào hàm. Điều này có thể giúp ngăn chặn các ảnh hưởng phụ. Chú ý: các Objectarray được destructure từ Object param thì không được sao chép lại.
  3. Sử dụng những tham số mặc định còn hơn là đi kiểm tradestructuring.
  • Không tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
4
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
5

Sử dụng cùng từ vựng cho cùng loại biến :

Sử dụng các tên dễ hiểu và tìm kiếm được :hàm thực hiện nhiều hơn 1 việc, chúng sẽ trở nên khó khăn hơn để viết code, test, và suy luận.

Khi bạn có thể tách biệt một hàm để chỉ thực hiện một hành động, thì sẽ dễ dàng hơn để tái cấu trúc và code của bạn sẽ dễ đọc hơn nhiều. Nếu bạn chỉ cần làm theo hướng dẫn này thôi mà không cần làm gì khác thì bạn cũng đã giỏi hơn nhiều developer khác rồi.hàm để chỉ thực hiện một hành động, thì sẽ dễ dàng hơn để tái cấu trúc và code của bạn sẽ dễ đọc hơn nhiều. Nếu bạn chỉ cần làm theo hướng dẫn này thôi mà không cần làm gì khác thì bạn cũng đã giỏi hơn nhiều developer khác rồi.

  • Không tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
6
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
7

Tên hàm phải nói ra được những gì chúng làm

Nhìn vào tên hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.

  • Không tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
8
  • Tốt :
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
9

Tên hàm phải nói ra được những gì chúng làm

Nhìn vào tên hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
0
  • Tốt :
getUserInfo();
getClientData();
getCustomerRecord();
1

Tên hàm phải nói ra được những gì chúng làm

Nhìn vào tên hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.hàm xử lý cùng một chức năng như nhau thì là việc phải tránh, đó là code trùng lặp. code trùng lặp thì không tốt bởi vì nếu bạn cần thay đổi cùng một logic, bạn phải sửa ở nhiều hơn một nơi.

Hàm chỉ nên có một lớp trừu tượng

Khi có nhiều hơn một lớp trừu tượng thì hàm của bạn đang làm quá nhiều. Chia nhỏ các hàm ra sẽ làm cho việc test và tái sử dụng dễ dàng hơn.code lặp lại bởi vì bạn có 2 hay nhiều hơn những thứ chỉ khác nhau chút ít, mà chia sẻ nhiều thứ chung, nhưng sự khác nhau của chúng buộc bạn phải có 2 hay nhiều hàm riêng biệt để làm nhiều điều tương tự nhau. Xóa đi những dòng code trùng có nghĩa là tạo ra một abstraction có thể xử lý tập những điểm khác biệt này chỉ với một hàm/module hay class.

Tránh trùng lặp codeabstraction đúng thì rất quan trọng, đó là lý do tại sao bạn nên tuân thủ các nguyên tắc SOLID được đặt ra trong phần class. Những abstraction không tốt có thể còn tệ hơn cả những dòng code bị trùng lặp, vì thế hãy cẩn thận! Nếu bạn có thể tạo ra một abstraction tốt, hãy làm nó! Đừng lặp lại chính mình, nếu bạn không muốn đi cập nhật nhiều nơi bất cứ khi nào bạn muốn thay đổi một thứ gì đó.

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
2
  • Tốt :
getUserInfo();
getClientData();
getCustomerRecord();
3

Tên hàm phải nói ra được những gì chúng làm

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
4
  • Tốt :
getUserInfo();
getClientData();
getCustomerRecord();
5

Tên hàm phải nói ra được những gì chúng làm

Nhìn vào tên hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.hàm thực hiện nhiều hơn một việc. hàm chỉ nên làm một nhiệm vụ. Vì vậy hãy tách hàm của bạn nếu chúng đang làm cho code rẽ nhánh dựa trên một biến boolean.

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
6
  • Tốt :
getUserInfo();
getClientData();
getCustomerRecord();
7

Tên hàm phải nói ra được những gì chúng làm

Nhìn vào tên hàm thôi mà chính bạn hoặc người khác cũng hiểu mục đích của hàm đó làm gì.hàm tạo ra ảnh hưởng phụ nếu nó làm bất kì điều gì khác hơn là nhận một giá trị đầu vào và trả về một hoặc nhiều giá trị. Ảnh hưởng phụ có thể là ghi một file, thay đổi vài biến toàn cục, hoặc vô tình đưa tất cả tiền của bạn cho một người lạ.

Hàm chỉ nên có một lớp trừu tượngfile. Những gì bạn cần làm là tập trung vào nơi bạn sẽ làm nó. Đừng viết hàmlớp riêng biệt để tạo ra một file cụ thể. Hãy có một service để viết nó. Một và chỉ một.

Khi có nhiều hơn một lớp trừu tượng thì hàm của bạn đang làm quá nhiều. Chia nhỏ các hàm ra sẽ làm cho việc test và tái sử dụng dễ dàng hơn.kiểu dữ liệu có thể thay đổi được mà có thể được ghi bởi bất cứ thứ gì, và không tập trung nơi có thể xảy ra các ảnh hưởng phụ. Nếu bạn có thể làm điều đó, bạn sẽ hạnh phúc hơn so với phần lớn các lập trình viên khác đấy.

  • Không tốt :
getUserInfo();
getClientData();
getCustomerRecord();
8
  • Tốt :
getUserInfo();
getClientData();
getCustomerRecord();
9

Tránh trùng lặp code

Việc có hai hàm xử lý cùng một chức năng như nhau thì là việc phải tránh, đó là code trùng lặp. code trùng lặp thì không tốt bởi vì nếu bạn cần thay đổi cùng một logic, bạn phải sửa ở nhiều hơn một nơi.JavaScript, các kiểu cơ bản được truyền theo giá trị và các đối tượng/mảng được truyền theo tham chiếu. Trong trường hợp các đối tượngmảng, ví dụ nếu hàm của chúng ta tạo ra thay đổi trong một mảng giỏ mua hàng, ví dụ thêm một sản phẩm để mua, thì bất kì hàm khác mà sử dụng mảng 'giỏ hàng' sẽ bị ảnh hưởng bởi việc thêm này. Điều này có thể tốt, tuy nhiên nó cũng có thể trở nên tồi tệ. Hãy tưởng tượng trường hợp xấu sau:

Hãy tưởng tượng nếu bạn điều hành một nhà hàng và bạn theo dõi hàng tồn kho: bao gồm cà chua, hành tây, tỏi, gia vị, vv.... Nếu bạn có nhiều danh sách quản lý, thì tất cả chúng phải được thay đổi khi bạn phục vụ một món ăn có chứa cà chua. Nếu bạn chỉ có 1 danh sách, thì việc cập nhật ở một nơi thôi.server. Do kết nối chậm, hàm mua có thể giữ việc thử lại yêu cầu. Bây giờ, nếu trong thời gian đó người sử dụng vô tình nhấn chuột vào nút "Thêm vào giỏ hàng" ở một sản phẩm mà họ không thực sự muốn trước khi mạng thực hiện yêu cầu? Nếu điều đó xảy ra và mạng bắt đầu gửi yêu cầu thì hàm mua sẽ vô tình thêm một sản phẩm vì nó có một tham chiếu đế mảng giỏ hàng mà hàm thêm sản phẩm vào giỏ hàng đã thay đổi bằng cách thêm một sản phẩm mà họ không muốn.

Thông thường, bạn có những dòng code lặp lại bởi vì bạn có 2 hay nhiều hơn những thứ chỉ khác nhau chút ít, mà chia sẻ nhiều thứ chung, nhưng sự khác nhau của chúng buộc bạn phải có 2 hay nhiều hàm riêng biệt để làm nhiều điều tương tự nhau. Xóa đi những dòng code trùng có nghĩa là tạo ra một abstraction có thể xử lý tập những điểm khác biệt này chỉ với một hàm/module hay class.hàm thêm sản phẩm vào giỏ hàng luôn luôn tạo một bản sao của giỏ, thay đổi nó, và trả về bản sao đó. Điều này đảm bảo rằng không một hàm nào có nắm giữ tham chiếu của giỏ mua hàng bị ảnh hưởng bởi bất kì thay đổi.

Hai lưu ý cho cách tiếp cận này:

  1. Có thể có những trường hợp mà bạn thực sự muốn thay đổi đối tượng đầu vào, nhưng khi bạn áp dụng phương pháp này bạn sẽ thấy những trường hợp này thì hiếm. Hầu hết các vấn đề có thể được cấu trúc lại để không còn ảnh hưởng phụ.
  2. Nhân bản các đối tượng lớn có thể ảnh hưởng đến hiệu năng. May mắn thay, đó không phải là một vấn đề lớn trong thực tế bởi vì có immutable-js cho phép cách tiếp cận này trở nên nhanh và ít tốn bộ nhớ so với khi bạn tự sao chép những đối tượng và mảng.immutable-js cho phép cách tiếp cận này trở nên nhanh và ít tốn bộ nhớ so với khi bạn tự sao chép những đối tượngmảng.
  • Không tốt :
getUser();
0
  • Tốt :
getUser();
1

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.

Hãy suy nghĩ ví dụ này: điều gì xảy ra nếu bạn muốn mở rộng phương thức của Array trong JavaScript native để có thể có một hàm

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 chỉ ra sự khác nhau giữa hai mảng? Bạn có thể viết một hàm mới với
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
3, nhưng nó có thể xung đột với một thư viện khác mà đã làm những điều tương tự. Điều gì xảy ra nếu thư viện đó chỉ sử dụng
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 để tìm sự khác biệt giữa phần tử đầu tiên và cuối cùng của một mảng? Đó là lý do tại sao sẽ là tốt hơn nhiều khi chỉ sử dụng các lớp ES2015/ES6 và đơn giản mở rộng Array toàn cục.Array trong JavaScript native để có thể có một hàm
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 chỉ ra sự khác nhau giữa hai mảng? Bạn có thể viết một hàm mới với
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
3, nhưng nó có thể xung đột với một thư viện khác mà đã làm những điều tương tự. Điều gì xảy ra nếu thư viện đó chỉ sử dụng
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 để tìm sự khác biệt giữa phần tử đầu tiên và cuối cùng của một mảng? Đó là lý do tại sao sẽ là tốt hơn nhiều khi chỉ sử dụng các lớp ES2015/ES6 và đơn giản mở rộng Array toàn cục.

  • Không tốt :
getUser();
2
  • Tốt :
getUser();
3

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm. không phải là ngôn ngữ lập trình hàm giống như là Haskell, nhưng nó có đặc trưng hàm của nó. Những ngôn ngữ lập trình hàm thì gọn gàng hơn và dễ test hơn. Hãy dùng cách lập trình này khi bạn có thể.

  • Không tốt :
getUser();
4
  • Tốt :
getUser();
5

Đừng ghi lên những hàm toàn cục

  • Không tốt :
getUser();
6
  • Tốt :
getUser();
7

Đừng ghi lên những hàm toàn cục

  • Không tốt :
getUser();
8
  • Tốt :
getUser();
9

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.đa hình để đạt được công việc tương tự trong rất nhiều trường hợp.

Hãy suy nghĩ ví dụ này: điều gì xảy ra nếu bạn muốn mở rộng phương thức của Array trong JavaScript native để có thể có một hàm

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 chỉ ra sự khác nhau giữa hai mảng? Bạn có thể viết một hàm mới với
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
3, nhưng nó có thể xung đột với một thư viện khác mà đã làm những điều tương tự. Điều gì xảy ra nếu thư viện đó chỉ sử dụng
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 để tìm sự khác biệt giữa phần tử đầu tiên và cuối cùng của một mảng? Đó là lý do tại sao sẽ là tốt hơn nhiều khi chỉ sử dụng các lớp ES2015/ES6 và đơn giản mở rộng Array toàn cục.hàm chỉ nên thực hiện một việc. Khi bạn có nhiều lớphàm mà có nhiều mệnh đề
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
5, bạn đang cho người dùng của bạn biết rằng hàm của bạn đang làm nhiều hơn một việc. Hãy nhớ, chỉ làm một công việc thôi.

  • Không tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
0
  • Tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
1

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm. không định kiểu, có nghĩa hàm của bạn có thể nhận bất kì đối số kiểu nào. Đôi khi bạn bị cám dỗ bởi sự tự do này và dễ dẫn đến việc đi kiểm tra kiểu trong hàm của mình. Có nhiều cách để tránh phải làm điều này. Điều đầu tiên là xem xét sử dụng các API nhất quán.

  • Không tốt :
Tốt :
  • Tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
3

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.chuỗi, số nguyênmảng, và bạn không thể sử dụng đa hình nhưng bạn vẫn cảm thấy cần phải kiểm tra kiểu, bạn nên xem xét sử dụng TypeScript. Nó là một phương pháp thay thế tuyệt vời cho JavaScript thường, vì nó cung cấp kiểu tĩnh ngoài cú pháp JavaScript chuẩn. Vấn đề với việc kiểm tra kiểu thủ công là để làm tốt việc này đòi hỏi nhiều sự dài dòng mà "kiểu an toàn" giả này không thay thế được cho việc mất đi tính dễ đọc của code. Hãy giữ code JavaScript của bạn sạch sẽ, viết test tốt và có reviews code tốt. Nếu không thì thực hiện tất cả những điều đó nhưng với TypeScript (giống như tôi đã nói, đó là sự thay thế tốt!).

  • Không tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
4
  • Tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
5

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.trình duyệt hiện đại làm rất nhiều tối ưu hóa bên dưới trong thời gian chạy. Rất nhiều lần, nếu bạn đang tối ưu thì bạn đang làm tốn thời gian của chính mình. Xem ở đây để biết khi nào việc tối ưu hóa là thiếu. Hãy thực hiện những tối ưu đó và cho đến khi chúng được sửa nếu có thể.

  • Không tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
6
  • Tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
7

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm. cũng tệ như code trùng lặp. Không có lý do gì để giữ chúng lại trong codebase của bạn. Nếu nó không được gọi nữa, hãy bỏ nó đi! Nó vẫn sẽ nằm trong lịch sử phiên bản của bạn nếu bạn vẫn cần nó.

  • Không tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
8
  • Tốt :
// 86400000 là cái quái gì thế?
setTimeout(blastOff, 86400000);
9

Đừng ghi lên những hàm toàn cục

Gây ảnh hưởng đến các biến toàn cục là một bad practice trong JavaScript vì bạn có thể xung đột với các thư viện khác và người dùng API của bạn sẽ không biết trước được cho đến khi cho một lỗi xảy ra trên sản phẩm.

Hãy suy nghĩ ví dụ này: điều gì xảy ra nếu bạn muốn mở rộng phương thức của Array trong JavaScript native để có thể có một hàm

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 chỉ ra sự khác nhau giữa hai mảng? Bạn có thể viết một hàm mới với
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
3, nhưng nó có thể xung đột với một thư viện khác mà đã làm những điều tương tự. Điều gì xảy ra nếu thư viện đó chỉ sử dụng
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
2 để tìm sự khác biệt giữa phần tử đầu tiên và cuối cùng của một mảng? Đó là lý do tại sao sẽ là tốt hơn nhiều khi chỉ sử dụng các lớp ES2015/ES6 và đơn giản mở rộng Array toàn cục.
không có
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
6 hoặc kiểu vì vậy rất khó để thực hiện mô hình này, bởi vì chúng ta không có các từ khoá như
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
7 và
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
8. Vì vậy, sử dụng
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
9 và
// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
00 để truy cập dữ liệu trên các đối tượng thì tốt hơn là chỉ đơn giản tìm kiếm một thuộc tính trên một đối tượng. Bạn có thể hỏi "Tại sao?".

Ủng hộ lập trình hàm hơn là lập trình mệnh lệnh

  1. Khi bạn muốn thực hiện nhiều hơn việc lấy một thuộc tính của đối tượng, bạn không cần phải tìm kiếm và thay đổi mỗi
    // ít nhất thì mình vẫn hiểu đây là ngày hiện tại
    const currentDate = moment().format('YYYY/MM/DD');
    
    01 trong codebase của bạn.codebase của bạn.
  2. Làm cho việc thêm các validation đơn giản khi thực hiện trên một tập hợp.validation đơn giản khi thực hiện trên một tập hợp.
  3. Đóng gói các biểu diễn nội bộ.
  4. Dễ dàng thêm log và xử lí lỗi khi
    // ít nhất thì mình vẫn hiểu đây là ngày hiện tại
    const currentDate = moment().format('YYYY/MM/DD');
    
    02 và
    // ít nhất thì mình vẫn hiểu đây là ngày hiện tại
    const currentDate = moment().format('YYYY/MM/DD');
    
    03.
  5. Kế thừa lớp này, bạn có thể
    // ít nhất thì mình vẫn hiểu đây là ngày hiện tại
    const currentDate = moment().format('YYYY/MM/DD');
    
    04 những hàm mặc định.
    này, bạn có thể
    // ít nhất thì mình vẫn hiểu đây là ngày hiện tại
    const currentDate = moment().format('YYYY/MM/DD');
    
    04 những hàm mặc định.
  6. Bạn có thể lazy load các thuộc tính của một đối tượng, lấy nó từ server.lazy load các thuộc tính của một đối tượng, lấy nó từ server.
  • Không tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
0
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
1

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).closures (cho ES5 và cũ hơn).

  • Không tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
0
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
3

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).

Lớplớp thừa kế, lớp khởi tạo, và các định nghĩa phương thức trong các lớp ES5 cổ điển. Nếu bạn cần kế thừa (và lưu ý rằng bạn có thể không), tốt hơn là nên sử dụng lớp. Tuy nhiên ưu tiên sử dụng những hàm nhỏ hơn là lớp cho đến khi bạn cần những đối tượng lớn và phức tạp hơn.

  • Không tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
4
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
5

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).pattern rất hữu ích trong JavaScript và bạn thấy nó trong rất nhiều thư viện chẳng hạn như jQueryLodash.

Lớpcode của bạn có tính truyền tải và ngắn gọn. Vì lý do đó, theo tôi, sử dụng phương pháp các hàm liên tiếp nhau và hãy xem code của bạn sẽ sạch sẽ như thế nào. Trong các hàm của lớp, đơn giản là trả về

// ít nhất thì mình vẫn hiểu đây là ngày hiện tại
const currentDate = moment().format('YYYY/MM/DD');
05 ở cuối mỗi hàm, và bạn có thể xâu chuỗi các phương thức khác vào trong nó.

  • Không tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
6
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
7

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).Design Patterns của Gang of Four, bạn nên sử dụng cấu trúc thành phần hơn là thừa kế nếu có thể. Có rất nhiều lý do tốt để sử dụng kế thừa cũng như sử dụng thành phần. Điểm nhấn cho phương châm này đó là nếu tâm trí của bạn đi theo bản năng thừa kế, thử nghĩ nếu thành phần có thể mô hình vấn đề của bạn tốt hơn. Trong một số trường hợp nó có thể.

Lớp

  1. Ưu tiên lớp ES2015/ES6 hơn các chức năng thuần ES5

  2. Rất khó khăn để có thể đọc được lớp thừa kế, lớp khởi tạo, và các định nghĩa phương thức trong các lớpES5 cổ điển. Nếu bạn cần kế thừa (và lưu ý rằng bạn có thể không), tốt hơn là nên sử dụng lớp. Tuy nhiên ưu tiên sử dụng những hàm nhỏ hơn là lớp cho đến khi bạn cần những đối tượng lớn và phức tạp hơn.

  3. Sử dụng các hàm liên tiếp nhau

  • Không tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
8
  • Tốt :
// MILLISECONDS_IN_A_DAY chúng ta hiểu phải không các bạn 
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
9

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).

LớpClean Code, "Chỉ có thể thay đổi một lớp vì một lí do duy nhất". Thật là hấp dẫn để nhồi nhét nhiều chức năng vào cho một lớp, giống như là khi bạn chỉ có thể lấy một chiếc vali cho chuyến bay vậy. Vấn đề là lớp của bạn sẽ không được hiểu gắn kết về mặt khái niệm của nó và sẽ có rất nhiều lí do để thay đổi. Việc làm giảm thiểu số lần bạn cần phải thay đổi một lớp là một việc quan trọng. Nó quan trọng bởi vì nếu có quá nhiều chức năng trong một lớp và bạn chỉ muốn thay đổi một chút xíu của lớp đó, thì có thể sẽ rất khó để hiểu được việc thay đổi đó sẽ ảnh hưởng đến những module khác trong codebase của bạn như thế nào.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
0
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
1

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn). đã nói "có thể thoải mái mở rộng một module, nhưng hạn chế sửa đổi bên trong module đó". Điều đó nghĩa là gì? Nguyên tắc này cơ bản nhấn mạnh rằng bạn phải cho phép người dùng thêm các chức năng mới mà không làm thay đổi các code đang có.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
2
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
3

Làm cho các đối tượng có thành viên private

Điều này có thể được thực hiện thông qua closures (cho ES5 và cũ hơn).

Lớp

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
4
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
5

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript. không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

Nguyên lí phân tách interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.

Một ví dụ tốt để minh hoạ cho nguyên lí này trong JavaScript là các lớp mà yêu cầu cài đặt các đối tượng lớn. Việc không yêu cầu người dùng thiết lập một số lượng lớn các tuỳ chọn là một ích lợi, bởi vì đa số thời gian họ không cần tất cả các cài đặt. Làm cho chúng trở thành tuỳ chọn giúp tránh được việc có một "fat interface".JavaScript là các lớp mà yêu cầu cài đặt các đối tượng lớn. Việc không yêu cầu người dùng thiết lập một số lượng lớn các tuỳ chọn là một ích lợi, bởi vì đa số thời gian họ không cần tất cả các cài đặt. Làm cho chúng trở thành tuỳ chọn giúp tránh được việc có một "fat interface".

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
6
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
7

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

  1. Nguyên lí phân tách interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.module cấp cao không nên phụ thuộc vào những module cấp thấp. Cả hai nên phụ thuộc vào abstraction.
  2. Một ví dụ tốt để minh hoạ cho nguyên lí này trong JavaScript là các lớp mà yêu cầu cài đặt các đối tượng lớn. Việc không yêu cầu người dùng thiết lập một số lượng lớn các tuỳ chọn là một ích lợi, bởi vì đa số thời gian họ không cần tất cả các cài đặt. Làm cho chúng trở thành tuỳ chọn giúp tránh được việc có một "fat interface". không nên phụ thuộc vào chi tiết, mà ngược lại.

Nguyên lí đảo ngược dependency (Dependency Inversion Principle)

Nguyên lí này khẳng định hai điều cần thiết sau:

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
8
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;

// mình đọc cái đống này thật ra cũng không hiểu
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
9

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript. thì quan trọng hơn shipping. Nếu bạn không có test hoặc không đủ, thì mỗi lần ship code bạn sẽ không chắc là mình có làm hư hại thứ gì không. Việc quyết định những gì để tạo thành số lượng test đủ là do team của bạn, nhưng việc có 100% độ bao phủ (tất cả các câu lệnh và rẽ nhánh) là cách để bạn đạt được sự tự tin cao. Điều này có nghĩa ngoài việc có được một framework để test tốt, bạn cũng cần sử dụng một công cụ bao phủ tốt.

Nguyên lí phân tách interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.framework test JS tốt, vì thế hãy tìm một framework mà team bạn thích. Khi đã tìm được một cái thích hợp với team của mình, hãy đặt mục tiêu để luôn luôn viết test cho mỗi tính năng hoặc module mới của bạn. Nếu phương pháp test ưa thích của bạn là Test Driven Development (TDD), điều đó thật tuyệt, nhưng điểm quan trọng là phải chắc chắn bạn đạt được mục tiêu về độ bao phủ trước khi launch một tính năng hoặc refactor một tính năng cũ nào đó.

Một ví dụ tốt để minh hoạ cho nguyên lí này trong JavaScript là các lớp mà yêu cầu cài đặt các đối tượng lớn. Việc không yêu cầu người dùng thiết lập một số lượng lớn các tuỳ chọn là một ích lợi, bởi vì đa số thời gian họ không cần tất cả các cài đặt. Làm cho chúng trở thành tuỳ chọn giúp tránh được việc có một "fat interface".

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
0
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
1

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

Nguyên lí phân tách interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
2
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
3

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
3
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
5

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

Nguyên lí phân tách interface nhấn mạnh rằng "Người dùng không nên bị bắt buộc phải phụ thuộc vào các interfaces mà họ không sử dụng." Interface là những ràng buộc ẩn trong JavaScript bởi vì duck typing.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
6
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
7

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.

  • Không tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
8
  • Tốt :
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

// đến đây thì mình hiểu đó là city và zipCode truyền vào
saveCityZipCode(city, zipCode);
9

Nguyên lí phân tách interface (Interface Segregation Principle)

JavaScript không có interface vì vậy nguyên lí này không áp dụng một cách chặt chẽ như các nguyên lí khác. Tuy nhiên, nó cũng quan trọng và liên quan ngay cả với hệ thống thiếu định kiểu của JavaScript.công cụ để tự động hoá việc này. Hãy sử dụng một công cụ nào đó! Thật tốn thời gian và tiền bạc chỉ để tranh cãi về vấn đề định dạng code.

Đối với những thứ không thuộc phạm vi của việc tự động định dạng code (thụt đầu dòng, tab và space, nháy đơn và nháy kép,..) hãy xem một số hướng dẫn ở đây.

Sử dụng thống nhất cách viết hoa

Javascript là một ngôn ngữ không định kiểu, vì vậy việc viết hoa sẽ nói lên rất nhiều về các biến, hàm,.. của bạn. Những quy tắc này thì mang tính chủ quan, vì thế team bạn có thể chọn quy tắc nào họ muốn. Tuy nhiên điều quan trọng là dù bạn chọn cách viết như thế nào, thì cũng hãy sử dụng thống nhất nó trong codebase của bạn.

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
0
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
1

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
2
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
3

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.

Viết chú thích

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
4
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
5

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
6
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
7

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
8
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
  //...
  // Khoan, cái 'l' gì thế ?
  dispatch(l);
});
9

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.

  • Không tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
0
  • Tốt :
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
  // ...
  // Hiểu cái `l` lúc nãy là cái gì rồi phải không các bạn :P
  dispatch(location);
});
1

Các hàm gọi và hàm được gọi nên nằm gần nhau

Nếu một hàm gọi một hàm khác, hãy giữ những hàm này nằm gần theo chiều dọc trong file. Lí tưởng là, hãy giữ cho hàm gọi ở trên hàm được gọi. Chúng ta có xu hướng đọc code từ trên xuống, giống như đọc báo vậy. Do đó, hãy làm cho code của chúng ta cũng được đọc theo cách đó.