Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

Các lớp so với mô -đun là câu hỏi sai

Câu hỏi bạn đang tìm kiếm là các lớp so với nguyên mẫu.classes vs. prototypes.

Show

Cả hai lớp và nguyên mẫu đều được sử dụng bởi các mô -đun.classes and prototypes are used by modules.

Các mô -đun (mô -đun ES2015) là những gì JavaScript sử dụng để có thể mã

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
2 và
export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
3. Trước khi JavaScript chính thức thực hiện các mô -đun, đã có các hack để thực hiện việc này và tạo ra đóng gói mã, điều này đã khắc phục các vấn đề như ô nhiễm phạm vi toàn cầu;
export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
4 là một ví dụ. Node.js với CommonJS và Angular với AMD và một số người khác đã cố gắng tìm ra cách thực hiện điều này theo cách tốt hơn và thực hiện hệ thống 'mô -đun' của riêng họ. Tôi muốn nghĩ rằng các mô -đun ES2015 bị ảnh hưởng bởi các ngôn ngữ khác và CommonJS/AMD, v.v. Và kết quả là, chúng tôi hiện có một hệ thống mô -đun trong JavaScript.

Đối với các lớp, bản thân họ tạo ra đóng gói mã, nhưng họ không thể tự xuất, đó là những gì các mô -đun làm. Điều tương tự cũng áp dụng cho mã dựa trên nguyên mẫu, nó tạo ra đóng gói mã nhưng không thể tự xuất nó giống như các lớp.

Bây giờ để đặt cái này lại với nhau.

Ví dụ về một mô -đun, ví dụ này không liên quan gì đến các lớp hoặc nguyên mẫu,

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
5:

const privateHello = 'hello' // <- module code (private)
export const publicHello = 'hello'; // <- module code (public)

Ví dụ về một mô -đun sử dụng một lớp,

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
6:

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)

Ví dụ về một mô -đun sử dụng các nguyên mẫu,

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
7:

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)

Điều làm cho sự khó hiểu này cho người mới bắt đầu đến từ các ngôn ngữ OOP là trong Java, một tệp lớp (file. class) được tự động xuất dưới dạng một lớp, đây là mặc định vì đây là cách Java hoạt động. Đây không phải là trường hợp trong JavaScript. Bạn phải nêu những gì bạn đang xuất khẩu.

Các lớp là một nỗ lực để thực hiện được gọi là

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
8 trong khi nguyên mẫu là, bạn đoán nó,
export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
9. Đây là hai cách để đối phó với công ty phản hồi mã và các đối tượng giữ trạng thái của riêng họ.code-reuse and objects that keep their own state.

Nếu chúng ta muốn làm cho mọi thứ trở nên phức tạp hơn, một câu hỏi tiếp theo tốt là

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
0. Nhưng bạn có thể đọc điều đó ở những nơi khác.

Chào. Tên tôi là "Adam" và tôi là nhà phát triển JavaScript. Bây giờ tôi đã không có lớp học, vì ... oh, chờ đã. Tôi nghĩ rằng tôi đang trộn lẫn các cuộc họp của mình.

Những độc giả thường xuyên của tôi (cả hai) đều biết rằng tôi cảm thấy khó chịu trước nỗi sợ phi lý của cộng đồng JS về từ khóa

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1. Một số ở đây thậm chí đã nói với tôi rằng tôi yêu các lớp học. Điều đó không thực sự đúng, nhưng tôi hiểu tại sao một số bước đến kết luận đó. Bởi vì không giống như rất nhiều nhà phát triển JS khác, tôi không bắt đầu nhổ và nguyền rủa bất cứ khi nào tôi thậm chí thấy từ khóa
export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 trong mã.

Nhưng tôi ở đây để nói với bạn rằng, trong một thời gian, tôi chưa viết bất kỳ lớp nào trong JavaScript. Ở tất cả. Mã React của tôi là tất cả các chức năng/móc dựa trên. Và tôi ổn với nó. Có thật không. Tôi thậm chí không bỏ lỡ các lớp học.

Tôi rất vui khi di chuyển mà không có lớp học vì một vài lý do chính. Trước hết, từ khóa

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 không là gì ngoài đường cú pháp trong JS. Nó không cung cấp bất kỳ chức năng mới nào mà bạn chưa có trong ngôn ngữ. Nó chỉ làm cho một số chức năng đó ... sạch hơn.

Ý tôi là gì khi "sạch hơn"? Chà ... gọi tôi là cáu kỉnh, nhưng tôi không bao giờ muốn viết thêm các đối tượng kiểu 24, nơi tôi đang nhảy qua các hoops của JS để hoàn thành những gì vừa phù hợp với mô hình

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1. Nhưng với các tiêu chuẩn Ecmascript "hiện đại", bạn thực sự không cần phải bận tâm với tất cả những thứ đó nữa. Cụ thể, tôi đang nói về mẫu thiết kế mô -đun.Module Design Pattern.

Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

Nó là gì??

Tôi biết điều này sẽ cảm thấy hơi cơ bản cho nhiều bạn, nhưng trước tiên hãy xác định những gì tôi muốn nói khi tôi nói "Mẫu thiết kế mô -đun". Giống như hầu hết các cuộc thảo luận về các mẫu thiết kế, định nghĩa theo nghĩa đen của "mẫu thiết kế mô -đun" có thể hơi ... mờ. Và khá thẳng thắn, cố gắng đi đến một sự đồng thuận khó khăn và nhanh chóng có thể cực kỳ nhàm chán.

Wikipedia định nghĩa mẫu mô -đun là:

Một mẫu thiết kế được sử dụng để thực hiện khái niệm các mô -đun phần mềm, được xác định bởi lập trình mô -đun, bằng ngôn ngữ lập trình với hỗ trợ trực tiếp không đầy đủ cho khái niệm này.

Ồ. Đó là vô cùng ... không có ích. Không tưởng tượng được. Khá nhiều vô dụng.

Vì vậy, hãy để tôi chỉ cho bạn những gì tôi hiểu là một "mẫu thiết kế mô -đun", cụ thể là nó áp dụng cho JavaScript.

export const MyModule = () => {
   return {};
};

Nhập chế độ FullScreenen EXIT Mode FullScreen

Đó là nó. Không, thực sự. Đó là nó. Chắc chắn, hầu hết các ví dụ thực tế sẽ có chi tiết hơn đáng kể cho họ. Nhưng ví dụ trên thực sự đủ điều kiện.

Nó thực sự chỉ là một chức năng - trả về một đối tượng. .

Bạn có thể nghĩ rằng đó chỉ là một chức năng đơn giản với một số cú pháp hiện đại (hàm mũi tên) và quy ước

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
2 hiện đại được thêm vào nó. Và - bạn sẽ đúng.

Bạn cũng có thể nhận thấy rằng tôi đã đặt tên cho mô-đun trong trường hợp Pascal, đây không phải là một phần của bất kỳ tiêu chuẩn nào cho mẫu thiết kế mô-đun. Nhưng tôi sẽ giải thích sau tại sao tôi làm điều đó.

Nếu bạn không có mối quan hệ nào ăn sâu vào mẫu mã ở trên, có lẽ đó là vì bạn không phải là nhà phát triển phản ứng ?? Lemme giải thích ...

Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

React & The Module Design Mẫu - Một quan hệ đối tác hoàn hảo

Trong những ngày khủng khiếp, không tốt, xấu, chúng ta thường viết các thành phần React như thế này:

export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Đó là nó. Không, thực sự. Đó là nó. Chắc chắn, hầu hết các ví dụ thực tế sẽ có chi tiết hơn đáng kể cho họ. Nhưng ví dụ trên thực sự đủ điều kiện.

Nó thực sự chỉ là một chức năng - trả về một đối tượng. .

export const MyComponent = () => {
  return <>
    <div>Here is some JSX</div>
  </>
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Đó là nó. Không, thực sự. Đó là nó. Chắc chắn, hầu hết các ví dụ thực tế sẽ có chi tiết hơn đáng kể cho họ. Nhưng ví dụ trên thực sự đủ điều kiện.

Nó thực sự chỉ là một chức năng - trả về một đối tượng. .

Bạn có thể nghĩ rằng đó chỉ là một chức năng đơn giản với một số cú pháp hiện đại (hàm mũi tên) và quy ước

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
2 hiện đại được thêm vào nó. Và - bạn sẽ đúng.

Bạn cũng có thể nhận thấy rằng tôi đã đặt tên cho mô-đun trong trường hợp Pascal, đây không phải là một phần của bất kỳ tiêu chuẩn nào cho mẫu thiết kế mô-đun. Nhưng tôi sẽ giải thích sau tại sao tôi làm điều đó.

export const useSomething = () => {
  const [statefulValue, setStatefulValue] = useState('');

  return {
    statefulValue,
  }
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong trường hợp này, chúng tôi không đối phó với JSX, nhưng điều này vẫn phù hợp hoàn hảo trong mẫu thiết kế mô -đun. Chúng tôi đang xuất một hàm, trả về các giá trị có lẽ đại diện cho một số khía cạnh của "trạng thái" bên trong của chính nó.

Nói cách khác, Afaik, gần như mọi móc tùy chỉnh mà tôi từng thấy tuân thủ các tiêu chuẩn (thừa nhận lỏng lẻo) về những gì bao gồm "mẫu thiết kế mô -đun". Đối với vấn đề đó, gần như mọi thành phần chức năng trong React cũng đáp ứng các tiêu chuẩn này.

BTW, nếu bạn nghĩ rằng đây chỉ là một cuộc triệt phá của các chức năng-VS, thì không phải vậy. Bởi vì có một số lợi ích hữu hình của mẫu thiết kế mô -đun. Để hiểu những điều đó là gì, chúng ta cần đánh giá cao cách JavaScript xử lý các chức năng ...

Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

Chức năng: Hộp ma thuật của JavaScript

IMA Hãy trung thực ở đây: Tôi đã mất một số năm trước khi tôi thực sự đánh giá cao điều này về JS. Trong JS, các chức năng là "công dân hạng nhất". Điều đó có nghĩa là, theo các điều khoản của Laymen, là chúng có thể được truyền xung quanh như một chuỗi, hoặc một số hoặc một đối tượng. Trong JS (hoặc bất kỳ ngôn ngữ nào khác có chức năng là "công dân hạng nhất"), chức năng không phải là chương trình con, nó là một giá trị theo đúng nghĩa của nó.

Điều đó có nghĩa là gì đối với mẫu thiết kế mô -đun của chúng tôi ???

Chà, hãy nhìn vào cái móc tùy chỉnh đơn giản chết ở trên. Nó đang trả lại một đối tượng. Và đối tượng đó có thể chứa ... về cơ bản là bất cứ điều gì - bao gồm cả các chức năng. Trong các ngôn ngữ khác, bạn có thể nghĩ về một cái gì đó cũng có thể chứa các chức năng ?? (Gợi ý: Trong các ngôn ngữ khác, các hàm đó thường được gọi là "Phương thức".)

Ví dụ, trong Java, một lớp là một mẫu cho phép bạn tạo (khởi tạo) các đối tượng. Đổi lại, những đối tượng đó có thể chứa ... về cơ bản mọi thứ - bao gồm các hàm (phương thức).

Trong JS,

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 chỉ là đường cú pháp. Nhưng nó là đường cú pháp để làm gì ??? Một số người cho rằng đó là đường cú pháp cho một đối tượng. Nhưng điều đó không hoàn toàn đúng.
export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 chỉ là đường cú pháp cho một hàm - một hàm trả về một đối tượng (do đó có thể chứa ... về cơ bản là bất cứ điều gì).

Trên thực tế, nếu bạn muốn lãng phí một đêm lặn sâu xuống hố thỏ JS, hãy thử viết một chức năng sẽ xác định liệu đối số được truyền lại có phải là một chức năng ... hoặc một lớp. Đó là ... không thể chết tiệt.

Tại sao tôi phải mất một thời gian để thực sự đánh giá cao điều này ?? Chà ... thật dễ dàng (thậm chí có thể tự nhiên) khi xem xét bất kỳ chức năng nào và cho rằng nó trả về một số giá trị vô hướng nào đó - một chuỗi, một số, ... bất cứ điều gì. Tất nhiên, tôi luôn hiểu rằng một hàm cũng có thể trả về các đối tượng, nhưng tôi vẫn nghĩ về các đối tượng đó về các giá trị vô hướng (nghĩa là, một đối tượng - có chứa các chuỗi hoặc một mảng - có chứa số).

Nhưng có thể không rõ ràng ngay lập tức đối với tất cả các lập trình viên rằng, trong JS, việc có một chức năng hoàn toàn tự nhiên là:

  1. Giữ các chức năng khác bên trong chức năng đó.
  2. Sử dụng một số chức năng đó chỉ cho các hoạt động nội bộ của chính nó ("riêng tư").
  3. Trả về một số chức năng đó cho người gọi ("công khai").

Nói cách khác, một hàm JS có thể thực hiện khá nhiều tất cả các hoạt động mà các nhà phát triển khác, trong các ngôn ngữ khác, gọi một lớp. Và một khi bạn nhận ra sức mạnh của các chức năng của JS, bạn nhận ra rằng các chức năng của JS là các lớp - chúng chỉ là các lớp trong quần áo của cừu.

Để đặt điều này vào một bối cảnh khác, tôi nhớ khi JQuery lần đầu tiên được áp dụng rộng rãi. Và tôi sẽ hoàn toàn trung thực ở đây - tôi nghĩ rằng nó trông hoàn toàn xa lạ với tôi vào thời điểm đó. Bởi vì JQuery về cơ bản là toàn bộ thư viện được xây dựng dựa trên khái niệm các chức năng ẩn danh. Và tại thời điểm đó trong cuộc sống lập trình của tôi, ý tưởng về một chức năng ẩn danh không có ý nghĩa gì với tôi. .

Ngay cả khi tôi cảm thấy thoải mái với cú pháp của JQuery, tôi đã không đánh giá cao mức độ mà nó làm nổi bật việc sử dụng các chức năng của JS như những công dân hạng nhất. Trớ trêu thay, tôi đã không hoàn toàn nắm bắt được một số "bài học" của JQuery cho đến nhiều năm sau khi tôi ngừng sử dụng nó.

Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

Các chức năng "tự nhận thức"

Một trong những lợi ích chính của các đối tượng OOP là chúng có một "sự tự nhận thức" về chúng. Không, tôi không có nghĩa là họ sẽ phối hợp một phản ứng chống lại loài người, dẫn đến sự gia tăng của máy móc. Tôi có nghĩa là họ có thể tiết lộ mọi thứ về bản thân - và ẩn những điều về bản thân họ.

Nhưng bạn không cần OOP để thực hiện điều này. Và đây là nơi mô hình thiết kế mô -đun tỏa sáng.

Xem xét ví dụ này:

export class MyClass {
  externalVariable = 'foo';
  internalTrackingVariable = 'bar';

  doExternalProcessing() {
    // function to be called by the instantiator
  }

  doInternalProcessing() {
    // internal helper function
  }
}
const myInstance = new MyClass();

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong ví dụ này,

export const MyModule = () => {
   return {};
};
1 và
export const MyModule = () => {
   return {};
};
2 có vẻ như các ứng cử viên chính là "riêng tư". Nhưng
export const MyModule = () => {
   return {};
};
3 có quyền truy cập đầy đủ vào chúng. Đó là ... không lý tưởng.

[Lưu ý 1: Có một đề xuất - chưa được hoàn thiện - để thêm các biến riêng tư vào các lớp JS. Nhưng vì nó vẫn chỉ là một đề xuất, tôi sẽ không dành thêm thời gian để suy nghĩ về nó ở đây.]

[Lưu ý 2: Hoàn toàn có thể tạo các biến/phương thức "riêng tư" bên trong JS

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1. Nó được gọi là đóng cửa. Nhưng cú pháp cần thiết cho nó không thực sự ... "trực quan" và nó không thực sự cảm thấy như nó là một phần của thông số
export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 theo bất kỳ cách nào.]

Bây giờ chúng ta hãy xem xét cùng một ví dụ với một mẫu thiết kế mô -đun:

export const MyModule = () => {
  const externalVariable = 'foo';
  const internalTrackingVariable = 'bar';

  const doExternalProcessing = () => {
    // function to be called by the instantiator
  }

  const doInternalProcessing = () => {
    // internal helper function
  }

  return {
    doExternalProcessing,
    externalVariable,
  }
}
const myInstance = MyModule();

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong ví dụ này,

export const MyModule = () => {
   return {};
};
1 và
export const MyModule = () => {
   return {};
};
2 có vẻ như các ứng cử viên chính là "riêng tư". Nhưng
export const MyModule = () => {
   return {};
};
3 có quyền truy cập đầy đủ vào chúng. Đó là ... không lý tưởng.

[Lưu ý 1: Có một đề xuất - chưa được hoàn thiện - để thêm các biến riêng tư vào các lớp JS. Nhưng vì nó vẫn chỉ là một đề xuất, tôi sẽ không dành thêm thời gian để suy nghĩ về nó ở đây.]

[Lưu ý 2: Hoàn toàn có thể tạo các biến/phương thức "riêng tư" bên trong JS

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1. Nó được gọi là đóng cửa. Nhưng cú pháp cần thiết cho nó không thực sự ... "trực quan" và nó không thực sự cảm thấy như nó là một phần của thông số
export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 theo bất kỳ cách nào.]

export const useSomeHook = () => {
  const [counter, setCounter] = useState(0);

  const updateCounter = (newCounter = 0) => {
    // apply some validation to ensure that newCounter
    // can ONLY be a non-negative integer
    setCounter(newCounter);
  }

  return {
    counter,
    updateCounter,
  }
}

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong ví dụ này,

export const MyModule = () => {
   return {};
};
1 và
export const MyModule = () => {
   return {};
};
2 có vẻ như các ứng cử viên chính là "riêng tư". Nhưng
export const MyModule = () => {
   return {};
};
3 có quyền truy cập đầy đủ vào chúng. Đó là ... không lý tưởng.

[Lưu ý 1: Có một đề xuất - chưa được hoàn thiện - để thêm các biến riêng tư vào các lớp JS. Nhưng vì nó vẫn chỉ là một đề xuất, tôi sẽ không dành thêm thời gian để suy nghĩ về nó ở đây.]

Hướng dẫn are javascript modules like classes? - các mô-đun javascript có giống như các lớp học không?

[Lưu ý 2: Hoàn toàn có thể tạo các biến/phương thức "riêng tư" bên trong JS export function Prototypes() { // <- module AND prototype code (public) const privateHello = 'hello'; // <- prototype code (private) this.publicHello = 'hello'; // <- prototype code (public) } // <- prototype code (public) const anotherPrivateHello = 'hello'; // <- module code (private) export const anotherPublicHello = 'hello'; // <- module code (public) 1. Nó được gọi là đóng cửa. Nhưng cú pháp cần thiết cho nó không thực sự ... "trực quan" và nó không thực sự cảm thấy như nó là một phần của thông số export function Prototypes() { // <- module AND prototype code (public) const privateHello = 'hello'; // <- prototype code (private) this.publicHello = 'hello'; // <- prototype code (public) } // <- prototype code (public) const anotherPrivateHello = 'hello'; // <- module code (private) export const anotherPublicHello = 'hello'; // <- module code (public) 1 theo bất kỳ cách nào.]

Bây giờ chúng ta hãy xem xét cùng một ví dụ với một mẫu thiết kế mô -đun:

Trong ví dụ

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1, mọi thứ đều "công khai", trừ khi chúng ta nhảy qua một số người đóng cửa để đảm bảo nó không như vậy. Nhưng trong ví dụ mô -đun, mọi thứ đều riêng tư, trừ khi chúng tôi chọn cụ thể để lộ nó trong đối tượng
export const MyModule = () => {
   return {};
};
7. Đột nhiên, việc kiểm soát các khía cạnh "tự nhận thức" của đối tượng sản phẩm cảm thấy quá dễ dàng hơn nhiều.

IMHO, đây là một lập luận lớn có lợi cho mô hình thiết kế mô -đun. Nếu người gọi

export const MyModule = () => {
   return {};
};
8 cố gắng truy cập
export const MyModule = () => {
   return {};
};
9, họ sẽ thấy rằng không có
export const MyModule = () => {
   return {};
};
1 để họ tham khảo.

Điều này cũng có sự phân nhánh rất lớn nếu chúng tôi cố gắng kiểm soát tính toàn vẹn dữ liệu của các thành viên "lớp" của chúng tôi. Cụ thể, khi tôi viết các móc tùy chỉnh, tôi thường xuyên sử dụng loại mẫu này:

Xem những gì tôi đã làm ở đó? Tôi có một biến trạng thái thường xuyên. Và tôi đang phơi bày giá trị trong đối tượng

export const MyModule = () => {
   return {};
};
7. Nhưng tôi không phơi bày người thiết lập tự nhiên. Thay vào đó, tôi chỉ hiển thị hàm
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
2 tùy chỉnh của mình, trước tiên sẽ đảm bảo chúng tôi có giá trị "phù hợp" trước khi đặt giá trị
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
3 mới.

Xem xét ví dụ này:

Tất nhiên, bạn chỉ có thể phơi bày

export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
4 trong đối tượng
export const MyModule = () => {
   return {};
};
7. Nhưng điều này có nghĩa là người gọi có thể đặt giá trị của
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
3 thành
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
7. Hoặc
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
8. Hoặc
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
9. Bằng cách chỉ hiển thị chức năng cập nhật tùy chỉnh của tôi, sau đó tôi có thể đảm bảo rằng
export class MyComponent extends React.Component {
  render() {
    return (
      <div>Here is some JSX</div>
    );
  }
}
3 chỉ được đặt thành giá trị "logic".

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
0

Nhập chế độ FullScreenen EXIT Mode FullScreen

Trong ví dụ này,

export const MyModule = () => {
   return {};
};
1 và
export const MyModule = () => {
   return {};
};
2 có vẻ như các ứng cử viên chính là "riêng tư". Nhưng
export const MyModule = () => {
   return {};
};
3 có quyền truy cập đầy đủ vào chúng. Đó là ... không lý tưởng.

[Lưu ý 1: Có một đề xuất - chưa được hoàn thiện - để thêm các biến riêng tư vào các lớp JS. Nhưng vì nó vẫn chỉ là một đề xuất, tôi sẽ không dành thêm thời gian để suy nghĩ về nó ở đây.]

[Lưu ý 2: Hoàn toàn có thể tạo các biến/phương thức "riêng tư" bên trong JS

export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1. Nó được gọi là đóng cửa. Nhưng cú pháp cần thiết cho nó không thực sự ... "trực quan" và nó không thực sự cảm thấy như nó là một phần của thông số
export function Prototypes() { // <- module AND prototype code (public)
    const privateHello = 'hello'; // <- prototype code (private)
    this.publicHello = 'hello'; // <- prototype code (public)
} // <- prototype code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1 theo bất kỳ cách nào.]

export class Classes { // <- module AND class code (public)
    private privateHello = 'hello'; // <- class code (private)
    public publicHello = 'hello'; // <- class code (public)
} // <- class code (public)
const anotherPrivateHello = 'hello'; // <- module code (private)
export const anotherPublicHello = 'hello'; // <- module code (public)
1

Nhập chế độ FullScreenen EXIT Mode FullScreen

Ở đó! Bây giờ bạn có hạnh phúc không ???

Sự khác biệt giữa lớp và mô -đun trong JavaScript là gì?

Các lớp được giới thiệu như một cách để mở rộng về kế thừa dựa trên nguyên mẫu bằng cách thêm một số khái niệm định hướng đối tượng. Các mô -đun được giới thiệu như một cách để tổ chức nhiều tệp mã trong JavaScript và mở rộng về khả năng tái sử dụng mã và phạm vi giữa các tệp.

Sự khác biệt giữa một lớp và một mô -đun là gì?

Sự khác biệt giữa một lớp và một mô -đun là gì?Các mô-đun là bộ sưu tập các phương thức và hằng số. Họ không thể tạo các phiên bản. Lớp học có thể tạo các trường hợp (đối tượng) và có trạng thái mỗi trường hợp (các biến thể hiện).Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).

Các mô -đun trong JavaScript là gì?

Một mô -đun trong JavaScript chỉ là một tệp chứa mã liên quan.Trong JavaScript, chúng tôi sử dụng các từ khóa nhập và xuất để chia sẻ và nhận các chức năng tương ứng trên các mô -đun khác nhau.Từ khóa xuất được sử dụng để tạo một biến, chức năng, lớp hoặc đối tượng có thể truy cập vào các mô -đun khác.a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules.

Có các lớp học trong JavaScript không?

Các lớp là một mẫu để tạo đối tượng.Họ gói gọn dữ liệu với mã để làm việc trên dữ liệu đó.Các lớp trong JS được xây dựng trên các nguyên mẫu nhưng cũng có một số cú pháp và ngữ nghĩa không được chia sẻ với ngữ nghĩa giống như lớp ES5.Classes in JS are built on prototypes but also have some syntax and semantics that are not shared with ES5 class-like semantics.