Biểu thức lambda của C # cũng có các bao đóng nhưng hiếm khi được thảo luận bởi các cộng đồng hoặc sách của C #. Tôi thấy nhiều người và sách JavaScript nói về sự đóng cửa của nó hơn là trong thế giới C #. Tại sao vậy?
Biểu thức lambda của C # cũng có các bao đóng nhưng hiếm khi được thảo luận bởi các cộng đồng hoặc sách của C #. Tôi thấy nhiều người và sách JavaScript nói về sự đóng cửa của nó hơn là trong thế giới C #. Tại sao vậy?
Câu trả lời:
Bởi vì javascript không có tính năng như không gian tên và bạn có thể gây rối khá dễ dàng với tất cả các loại đối tượng toàn cầu.
Vì vậy, điều quan trọng là có thể cô lập một số mã trong môi trường thực thi của chính nó. Đóng cửa là hoàn hảo cho điều đó.
Việc sử dụng bao đóng này không có ý nghĩa trong một ngôn ngữ như C # nơi bạn có không gian tên, lớp và vv để cô lập mã và không đặt mọi thứ trong phạm vi toàn cầu.
Một thực tế rất phổ biến đối với mã javascript là viết nó như thế này:
(function(){
// Some code
})();
Như bạn có thể thấy, đây là một khai báo hàm ẩn danh, ngay sau đó là sự thực thi của nó. Do đó, mọi thứ được xác định trong hàm là không thể truy cập từ bên ngoài và bạn sẽ không làm rối phạm vi toàn cầu. Bối cảnh thực thi của hàm này sẽ vẫn tồn tại miễn là một số mã sử dụng nó, giống như các hàm lồng nhau được xác định trong ngữ cảnh này, mà bạn có thể chuyển như gọi lại hoặc bất cứ điều gì.
Javascript là một ngôn ngữ rất khác so với C #. Nó không hướng đối tượng, nó là định hướng nguyên mẫu. Điều này dẫn đến thực tiễn rất khác nhau ở cuối.
Dù sao, đóng cửa là tốt, vì vậy hãy sử dụng chúng, ngay cả trong C #!
EDIT: Sau một số thảo luận về trò chuyện của stackoverflow, tôi nghĩ rằng anwer này phải được ưu tiên.
Hàm trong mã mẫu không phải là một bao đóng. Tuy nhiên, fucntion này có thể định nghĩa các biến cục bộ và các hàm lồng nhau. Tất cả các hàm lồng nhau sử dụng các biến cục bộ này là các bao đóng.
Điều này là hữu ích để chia sẻ một số dữ liệu trên một tập hợp các chức năng mà không làm rối phạm vi toàn cầu. Đây là cách sử dụng phổ biến nhất của đóng trong javascript.
Việc đóng cửa mạnh mẽ hơn nhiều so với việc chỉ chia sẻ một số dữ liệu như thế này, nhưng hãy thực tế, hầu hết các lập trình viên không biết gì về lập trình hàm. Trong C #, bạn sẽ sử dụng lớp hoặc không gian tên cho các loại sử dụng này, nhưng JS không cung cấp chức năng này.
Bạn có thể làm nhiều cách hơn với việc đóng cửa hơn là chỉ bảo vệ phạm vi toàn cầu, nhưng đây là những gì bạn sẽ thấy trong mã nguồn JS.
Có lẽ bởi vì việc triển khai phổ biến hướng đối tượng của JavaScript phụ thuộc vào các bao đóng. Hãy xem xét một ví dụ đơn giản:
function counter() {
var value = 0;
this.getValue = function() { return value; }
this.increase = function() { value++; }
}
var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());
Các phương thức getValue
và increase
trong thực tế đóng, đóng gói các biến value
.
Bởi vì nhiều thư viện làm cho JavaScript 'có thể chịu được' sử dụng chúng.
Hãy xem JQuery , Prototype hoặc MooTools , chỉ để đặt tên cho ba phổ biến. Mỗi thư viện đó cung cấp một each
phương thức cho các bộ sưu tập của họ như là cách lặp ưa thích, sử dụng hàm lặp. Hàm đó, khi truy cập các giá trị trong phạm vi bên ngoài, sẽ là một bao đóng:
[1,2,3].each(function(item) {
console.log(item);
});
Và nó không dừng lại ở đó: Các cuộc gọi lại trong Ajax, xử lý sự kiện trong Ext.js, v.v.
console.log
được xác định trong một phạm vi bên ngoài, do đó, console
một 'biến miễn phí'. Và, tại sao, trong thực tế, một vòng lặp for, không có gì khác biệt, một thực tiễn xấu?
Tôi đồng ý với các câu trả lời khác rằng mã hóa "tốt" với JavaScript phụ thuộc nhiều hơn vào các bao đóng. Tuy nhiên, bên cạnh đó, có lẽ chỉ là một câu hỏi về tính năng đã tồn tại bao lâu trong mỗi ngôn ngữ. JavaScript về cơ bản đã đóng cửa kể từ khi triển khai sớm nhất. Mặt khác, C # chỉ có chúng kể từ 3.0, được phát hành cùng với Visual Studio 2008.
Rất nhiều lập trình viên C # tôi chạy vào vẫn đang làm việc trên các dự án 2.0. Và ngay cả khi họ đang làm việc trong 3.0 hoặc 4.0, họ vẫn thường sử dụng thành ngữ 2.0. Tôi yêu sự khép kín; hy vọng chúng sẽ được sử dụng nhiều hơn trong C # khi khái niệm này lan truyền giữa các nhà phát triển C #.
Lý do chính là vì C # được gõ tĩnh và các chức năng chỉ có quyền truy cập vào một môi trường duy nhất, được xác định trước, cản trở tính hữu ích của việc đóng cửa.
Mặt khác, trong JavaScript, các bao đóng cho phép các hàm hoạt động như các phương thức khi được truy cập như một thuộc tính đối tượng và là các đối tượng hạng nhất, chúng cũng có thể được đưa vào các môi trường khác nhau cho phép các chương trình con hoạt động trong các bối cảnh khác nhau.
Một lý do tôi phải tìm hiểu về chúng là vì khi bạn lặp qua các phần tử DOM (hoặc bất cứ thứ gì thực sự), bạn muốn có thể "đóng" hoặc "đóng gói" phạm vi biến. Như trong ví dụ được đăng ở đây: /programming/5606059/how-to-create-clenses-in-loop-and-store-it-in-variable-for-later-execut