Hãy nói về môi trường. Hành tinh của chúng ta rất lớn, nhưng tất cả chúng ta đều chia sẻ nó. Nếu bạn xây dựng một nhà máy hóa chất, sẽ rất tốt nếu bạn cách ly nó với thế giới bên ngoài để những gì xảy ra trong đó vẫn ở bên trong. Có thể nói tòa nhà này có môi trường, vi khí hậu, biệt lập với môi trường bên ngoài.
Bao đóng là khi một chức năng “nhớ” phạm vi từ vựng của nó ngay cả khi chức năng được thực thi bên ngoài phạm vi từ vựng đó
Phạm vi trong JavaScript
Javascript sử dụng chuỗi phạm vi để thiết lập phạm vi cho một chức năng nhất định. Thường có một phạm vi toàn cầu và mỗi chức năng được xác định có phạm vi lồng nhau của riêng nó. Bất kỳ chức năng nào được xác định trong một chức năng khác đều có phạm vi cục bộ được liên kết với chức năng bên ngoài
Các cách tạo phạm vi trong JavaScript thông qua. khối try-catch, chức năng, từ khóa let với dấu ngoặc nhọn trong số những thứ khác
var initialAmount = 0 // Global Scope
function deposit [totalamount] {
/**
* Local Scope
* Code here has access to anything declared in the global scope
*/
var newAmount = parseInt[initialAmount] + parseInt[totalamount]
return newAmount}
Mỗi hàm trong JavaScript tạo phạm vi cục bộ của riêng nó khi được khai báo
Điều này có nghĩa là bất cứ thứ gì được khai báo bên trong phạm vi cục bộ của hàm đều không thể truy cập được từ bên ngoài. Hãy xem với ví dụ dưới đây
var initialAmount = 300 // Variable declared in the Global Scope
function withdraw [totalamount] {
var balance // Variable declared in function scope
balance = parseInt[initialAmount] - parseInt[totalamount]
return balance
}
console.log[initialAmount]
// Will output initialAmountvalue as it's declared in the global scopeconsole.log[balance]
// ReferenceError: Can't find variable: balance
Phạm vi từ vựng
Phạm vi từ vựng của JavaScript được xác định trong giai đoạn biên dịch. Nó đặt phạm vi của một biến sao cho nó chỉ có thể được gọi/tham chiếu từ bên trong khối mã mà nó được xác định
Một hàm được khai báo bên trong một khối chức năng xung quanh có quyền truy cập vào các biến trong phạm vi từ vựng của hàm xung quanh
var initialAmount = 300 // Global Scope
function withdraw [totalamount] {
/**
* Local Scope
* Code here has access to anything declared in the global scope
*/
var balance = parseInt[initialAmount] - parseInt[amount]
const actualAmount = [function [] {
const TRANSACTIONCOST = 35
return balance - TRANSACTIONCOST /**
* Accesses Amount variable from the lexical scope
*/
}][] // Immediately Invoked Function expression. IIFE
// console.log[TRANSACTIONCOST]
// ReferenceError: Can't find variable: TRANSACTIONCOST
return actualAmount}
Việc gọi một hàm bên trong bên ngoài hàm kèm theo của nó nhưng vẫn duy trì quyền truy cập vào các biến trong hàm kèm theo của nó [phạm vi từ vựng] sẽ tạo ra một JavaScript Closure
function person [] {
var name = 'Renu' // Local variable var actions = {
speak: function [] {
// new function scope
console.log['My name is ', name] /**
* Accessing the name variable from the outer
function scope [lexical scope]
*/
}
} // actions object with a function return actions /**
* We return the actions object
* We then can invoke the speak function outside this scope
*/
}person[].speak[] // Inner function invoked outside its lexical Scope
A Closure cho phép chúng ta hiển thị một giao diện công khai đồng thời ẩn và bảo toàn ngữ cảnh thực thi khỏi phạm vi bên ngoài. Một số mẫu thiết kế JavaScript sử dụng bao đóng
Mẫu mô-đun
Biết những gì chúng ta biết về bao đóng, chúng ta có thể tạo các đối tượng bằng cách sử dụng mẫu mô-đun. Bằng cách trả về một đối tượng hoặc biến và gán nó cho một biến bên ngoài hàm, chúng ta có thể hiển thị bất cứ thứ gì chúng ta muốn ra thế giới bên ngoài, vì vậy chúng ta có thể có cả phương thức công khai và riêng tư
var Module = [function [] {
var foo = 'foo' // Private Property
function addToFoo [bam] { // Private Method
foo = bam
return foo
}
var publicInterface = {
bar: function [] { // Public Method
return 'bar'
},
bam: function [] { // Public Method
return addToFoo['bam'] // Invoking the private method
}
}
return publicInterface // Object will contain public methods
}][]
Module.bar[] // barModule.bam[] // bam
Từ hình minh họa mẫu mô-đun ở trên, chỉ các phương thức và thuộc tính công khai trong đối tượng trả về sẽ khả dụng bên ngoài ngữ cảnh thực thi của bao đóng
Khi chúng ta chuyển một hàm vào setTimeout hoặc bất kỳ loại gọi lại nào. Hàm vẫn nhớ phạm vi từ vựng do đóng
Tất cả các thành viên riêng tư sẽ vẫn tồn tại vì bối cảnh thực thi của chúng được giữ nguyên nhưng bị ẩn khỏi phạm vi bên ngoài