Lợi ích của việc đóng cửa trong JavaScript là gì?

Bao đóng là sự kết hợp của một chức năng được nhóm lại với nhau (kèm theo) với các tham chiếu đến trạng thái xung quanh của nó (môi trường từ vựng)

Nói cách khác, một bao đóng cho phép bạn truy cập vào phạm vi của chức năng bên ngoài từ một chức năng bên trong. Trong JavaScript, các bao đóng được tạo mỗi khi một hàm được tạo, tại thời điểm tạo hàm

Phạm vi từ vựng

Hãy xem xét mã ví dụ sau

function outer() {
var a = 5;
function inner(){
console.log(a);
}
inner();
}
outer(); //5

Ở đây,

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
4 tạo một biến cục bộ có tên là
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
5 và một hàm có tên là
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6. Hàm
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 là một hàm bên trong được xác định bên trong
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
4 và chỉ khả dụng trong phần thân của hàm
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
4. Lưu ý rằng hàm
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 không có biến cục bộ của riêng nó. Tuy nhiên, vì các hàm bên trong có quyền truy cập vào các biến của các hàm bên ngoài, nên
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 có thể truy cập biến
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
5 được khai báo trong hàm cha,
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
4

Lưu ý rằng câu lệnh

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
14 trong hàm
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 hiển thị thành công giá trị của biến
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
5, được khai báo trong hàm mẹ của nó. Đây là một ví dụ về phạm vi từ vựng, mô tả cách trình phân tích cú pháp giải quyết các tên biến khi các hàm được lồng vào nhau. Từ vựng đề cập đến thực tế là phạm vi từ vựng sử dụng vị trí mà một biến được khai báo trong mã nguồn để xác định vị trí của biến đó. Các hàm lồng nhau có quyền truy cập vào các biến được khai báo trong phạm vi bên ngoài của chúng

Về cơ bản ở đây,

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 được gói cùng với môi trường từ vựng của nó là
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
4. Đầu tiên,
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 sẽ kiểm tra phạm vi cục bộ của nó; . Vì vậy, bên trong
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6, nó tạo thành một bao đóng với biến là một phần của phạm vi từ vựng bên ngoài i. e. ,
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6bị ràng buộc với các biến của
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
03

  • Khi các hàm được trả về từ một hàm khác, chúng vẫn duy trì phạm vi từ vựng của mình. e. , họ nhớ nơi họ thực sự có mặt
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5

Đến đây, ________ 203 không còn tồn tại. Tuy nhiên,

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6 nhớ phạm vi từ vựng của nó i. e. , khi chúng tôi trả về
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6, không chỉ mã hàm được trả về mà còn trả về một bao đóng (hàm cùng với phạm vi từ vựng)

  • Một đặc điểm quan trọng của bao đóng là nó giữ trạng thái của biến bên ngoài giữa nhiều lần gọi. Hàm bên trong không chứa một bản sao riêng biệt của biến, nó chỉ giữ tham chiếu của biến bên ngoài
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
1

Ở đây cũng có

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6will đi kèm với phạm vi từ vựng i. e.
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
5sẽ không đề cập đến giá trị, nó sẽ đề cập đến tham chiếu của nó

  • Nếu chúng ta thay đổi khai báo biến cục bộ thành
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    09 và nếu chúng ta truyền thêm một tham số
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    90 vào
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    4, thì trong cả hai trường hợp, hàm bên trong vẫn tạo thành một bao đóng. Đó là bởi vì
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    90 cũng là một phần của môi trường bên ngoài của chức năng bên trong
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
0

Chuỗi phạm vi đóng cửa

Mỗi bao đóng có ba phạm vi

  • Phạm vi cục bộ (Phạm vi riêng)
  • Phạm vi chức năng bên ngoài
  • Phạm vi toàn cầu

Để chứng minh, hãy xem xét mã ví dụ sau

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
9

  • Bây giờ nếu chúng ta có một biến toàn cục với tên xung đột i. e cùng tên biến
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 có mặt trên toàn cầu và trong hàm ngoài. Sau đó, trong trường hợp này, giá trị
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 bên trong hoặc phạm vi chức năng khác của hàm
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 sẽ được trả về. Và toàn cầu
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 là biến hoàn toàn mới trong phạm vi toàn cầu. Vì vậy, cả hai biến
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 là hoàn toàn khác nhau. Ở đây
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5 có mặt ở môi trường bên ngoài, nếu không có mặt thì nó sẽ toàn cầu
    function outer() {
    var a = 5;
    function inner(){
    console.log(a);
    }
    return inner;
    }
    var x = outer();
    x(); //5
    outer()() //5
    5
________ 41 Ưu điểm của Đóng cửa

1) Sử dụng các biến và phương thức riêng

Các ngôn ngữ như Java cung cấp khả năng khai báo các phương thức riêng tư, nghĩa là chúng chỉ có thể được gọi bởi các phương thức khác trong cùng một lớp. JavaScript không cung cấp cách riêng để thực hiện việc này, nhưng có thể mô phỏng các biến và phương thức riêng tư bằng cách sử dụng các bao đóng

2) Ẩn và đóng gói dữ liệu

Bao đóng có thể ẩn dữ liệu bằng cách tạo các biến riêng i. e các chức năng hoặc đoạn mã khác sẽ không có quyền truy cập vào dữ liệu cụ thể đó. Có thể nói chúng ta có thể đóng gói dữ liệu để phần khác của chương trình không thể truy cập được. Hãy hiểu điều này với sự giúp đỡ của một ví dụ

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
2

Ở đây, biến

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
10 là riêng tư hoặc ẩn và sẽ không thể truy cập được bên ngoài hàm truy cập.
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
11 và
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
12 là các biến hoàn toàn khác nhau với phạm vi khác nhau

Bây giờ nếu chúng ta cũng muốn thêm bộ đếm giảm dần thì cách tốt nhất và có thể mở rộng là tạo hàm tạo hàm

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
6

3) Chức năng Curry

Bao đóng làm cho cà ri có thể có trong JavaScript. Currying là một kỹ thuật nâng cao để làm việc với các hàm. Currying là một phép biến đổi các hàm để dịch một hàm từ có thể gọi là

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
13 thành có thể gọi là
function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
14. Đó là khi bạn chia nhỏ một hàm nhận nhiều đối số thành một loạt các hàm mà mỗi hàm chỉ nhận một đối số

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
9

Đây là một hàm nhận hai đối số a và b và trả về tổng của chúng. Bây giờ chúng ta sẽ cà ri chức năng này

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
0

Đây là một hàm nhận một đối số a và trả về một hàm nhận một đối số khác b và hàm đó trả về tổng của nó

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
0

Câu lệnh đầu tiên trả về 7, giống như câu lệnh add(3, 4). Câu lệnh thứ hai định nghĩa một hàm mới gọi là add3 sẽ thêm 3 vào đối số của nó. Đây là những gì một số người có thể gọi là đóng cửa. Câu lệnh thứ ba sử dụng thao tác add3 để cộng 3 với 4, kết quả lại là 7

Để biết thêm chi tiết tham khảo — JavaScript Currying. Hướng dẫn toàn diện

4) Nhà máy chức năng

Một công dụng mạnh mẽ của bao đóng là sử dụng chức năng bên ngoài như một nhà máy để tạo các chức năng có liên quan nào đó.

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
1

Sử dụng các bao đóng làm nhà máy chức năng là một cách tuyệt vời để giữ cho JavaScript của bạn KHÔ. Năm dòng mã mạnh mẽ cho phép chúng tôi tạo bất kỳ số lượng chức năng nào với các mục đích tương tự nhưng độc đáo

5) Chỉ chạy chức năng một lần

Các chức năng ghi nhớ số lần chức năng đã được chạy bằng cách tạo một bao đóng

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
2

6) đặt hết giờ

Đó là một phương thức gọi một hàm hoặc đánh giá một biểu thức sau một số mili giây đã chỉ định

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
3

Ở đây, chức năng trong setTimeout tạo thành một bao đóng. Vì vậy, hàm này ghi nhớ tham chiếu đến “i”. Vì vậy, bất cứ nơi nào chức năng này đi, nó sẽ nhận giá trị của “i” với nó. setTimeout nhận chức năng gọi lại và lưu trữ nó ở một nơi nào đó và gắn bộ hẹn giờ vào đó. Khi bộ đếm thời gian hết hạn, nó sẽ nhận chức năng và đặt nó vào ngăn xếp cuộc gọi hiện tại và chạy nó

7) Ghi nhớ

Ghi nhớ là thực hành có lập trình để làm cho các hàm lặp/đệ quy dài chạy nhanh hơn nhiều. Đóng cửa cũng được sử dụng ở đây. Đây là một ví dụ về hàm

function outer() {
var a = 5;
function inner(){
console.log(a);
}
return inner;
}
var x = outer();
x(); //5
outer()() //5
15 cơ bản

8) Các bao đóng cũng được sử dụng để duy trì trạng thái trong thế giới không đồng bộ, trong các trình vòng lặp và trong các mẫu thiết kế mô-đun