fbpx
close

Closure là gì? Tìm hiểu về Closure trong JavaScript

Tác giả: TinoHost Ngày cập nhật: 29/01/2024 Chuyên mục: Webmasters
Disclosure
Website Wiki.tino.org được cung cấp bởi Tino Group. Truy cập và sử dụng website đồng nghĩa với việc bạn đồng ý với các điều khoản và điều kiện trong chính sách bảo mật - điều khoản sử dụng nội dung. Wiki.tino.org có thể thay đổi điều khoản sử dụng bất cứ lúc nào. Việc bạn tiếp tục sử dụng Wiki.tino.org sau khi thay đổi có nghĩa là bạn chấp nhận những thay đổi đó.
Why Trust Us
Các bài viết với hàm lượng tri thức cao tại wiki.tino.org được tạo ra bởi các chuyên viên Marketing vững chuyên môn và được kiểm duyệt nghiêm túc theo chính sách biên tập bởi đội ngũ biên tập viên dày dặn kinh nghiệm. Mọi nỗ lực của chúng tôi đều hướng đến mong muốn mang đến cho cộng đồng nguồn thông tin chất lượng, chính xác, khách quan, đồng thời tuân thủ các tiêu chuẩn cao nhất trong báo cáo và xuất bản.

Có lẽ bạn chưa biết rằng, có rất nhiều người “rớt phỏng vấn xin việc” chỉ vì Closure đấy! Vậy, Closure là gì? Tại sao Closure lại xuất hiện nhiều trong những buổi phỏng vấn đến như vậy? Đừng lo, Tino Group sẽ giải đáp những câu hỏi này và giúp bạn hiểu thêm về Closure trong JavaScript thông qua một số ví dụ nhé!

Tìm hiểu về Closure

Closure là gì?

Closure là một hàm được viết lồng vào trong một hàm khác và Closure có thể sử dụng biến toàn cục, biến cục bộ của hàm (hàm cha) ngay cả khi đã đóng và sử dụng biến cục bộ của bản thân Closure.

Trong JavaScript, Closure là một thuộc tính rất mạnh. Không chỉ JavaScript, Closure còn có mặt trong hầu hết các loại ngôn ngữ lập trình khác.

Trong JavaScript, Closure có 3 phạm vi truy cập biến số khác nhau bao gồm:

  • Biến ở trong hàm Closure
  • Biến được khai báo ở hàm cha chứa Closure (outer function)
  • Biến toàn cục (global)
closure-la-gi

Hàm Closure ra sao?

Bên cạnh lý thuyết, chúng ta sẽ đi tìm hiểu về ví dụ để rõ hơn về Closure nhé!

Trước tiên, ta sẽ xem xét ví dụ về Lexical scoping như sau:

function outerFuc() {
var name = 'Mai Truc Lam';
function innerFunc() {
console.log(name);
}
innerFunc();
}
outerFuc(); // Kết quả: Mai Truc Lam

Trong đó, ta có:

  • Biến toàn cục: name
  • Function functionOuter(function cha)
  • Function innerFunc, trong function innerFunc không có biến toàn cục nào nhưng trong hàm đang sử dụng một biến name của function functionOuter.

Thay đổi code một tí, chúng ta sẽ có Closure như sau:

function outerFuc() {
var name = 'Mai Truc Lam';
function innerFunc() {
console.log(name);
}
return innerFunc;
}
var refInnerFunc = outerFuc();
refInnerFunc(); // Kết quả: Mai Truc Lam

Có vẻ, bạn cũng đã thấy sự khác biệt ở đây rồi đúng không nào? Trong đoạn code thứ 2, chúng ta sẽ thấy:

Hàm refInnerFunc đang gáng và tham chiếu đến kết quả của hàm outerFuc(); refInnerFunc trỏ đến hàm innerFunc nhưng chưa thực thi.

Sau khi hàm outerFuc() thực thi xong, biến toàn cục của hàm sẽ được giải phóng

Khi hàm innerFunc() thực thi sẽ ra kết quả là Mai Truc Lam. Nhưng kết quà này là của hàm cha outerFuc(). Nhưng điều này nghe có vẻ vô lý về mắt lý thuyết đúng không?

Nhưng trong JavaScript, khi 1 hàm nằm trong 1 hàm khác, nếu hàm cha thực thi trước sẽ tạo ra một môi trường Lexical đặt tất cả các biến đang có vào và gắn cho hàm con (trong ví dụ là: refInnerFunc) để sử dụng.

Cũng có thể giải thích như sau: khi hàm outerFuc() “chết” đi sẽ để lại “di chúc” cho hàm con refInnerFunc() là một biến name, sau khi hàm innerFunc() “chết” theo biến mới được giải phóng.

Trong ví dụ trên, chúng ta có thể thấy được hàm refInnerFunc() là Closure, vì hàm này đang ở trong 1 hàm khác và có thể sử dụng biến name của hàm cha outerFuc(). Nếu có cả biến cục bộ của bản thân refInnerFunc() và biến global, refInnerFunc() cúng có thể sử dụng được.

refInnerFunc() sẽ tham chiếu đến môi trường Lexical và hàm innerFunc().

Ứng dụng của Closure trong thực tế là gì?

Trong thực tế, ta sẽ thấy Closure có khá nhiều ứng dụng như:

Để hiểu hơn, chúng ta lại đi vào ví dụ về 3 ứng dụng trên nhé!

Function factory

Chúng ta sẽ có code như sau:

function makeExponentiation(x) {
var exponent = x;
return function(y) {
return Math.pow(y, exponent);
}
}
var sqr = makeExponentiation(2);
var sqrt = makeExponentiation(0.5);
console.log('3 squared is ' + sqr(3));
console.log('căn bậc hai của 9 là ' + sqrt(9));

Trong đó, bạn có thể thấy hàm makeExponentiation giống như một Function factory khi có thể tạo ra được những Function tùy vào tham số truyền vào. 2 Closure: sqrt sqr sở hữu body giống nhau nhưng khác biến tương đương (ENV – Variable Equivalent).

closure-la-gi

Mô phỏng lại phạm vi của biến trong lập trình hướng đối tượng

Bên trong JavaScript chưa có khái niệm class đúng nghĩa như trong C++ hay những ngôn ngữ lập trình khác. Trong ES6, cuối cùng, khái niệm class trong JavaScript cũng có. Tuy nhiên, về bản chất đây là một phương pháp giả lập/ mô phỏng/ hack bằng cách sử dụng Closure. Bạn có thể xem code sau đây:

function Counter() {
var counter = 0;
function add(number) {
counter += number;
}
return {
increment: function() {
add(1);
},
decrement: function() {
add(-1);
},
value: function() {
return counter;
}
};
});
var counter = Counter();
console.log('giá trị ban đầu’ + counter.value());
counter.increment();
counter.increment();
console.log('sau khi tăng lên 1' + counter.value());
counter.decrement();
console.log('sau khi giảm xuống 1 ' + counter.value());

Trong đó, các hàm increment, decrement value đều là Closure có body khác nhau nhưng chia sẻ cùng một Variable Equivalent.

Chia sẻ chung Variable Equivalent chính là “bí quyết” mô phỏng class trong JavaScript. Khi Closure update một biến, việc này đổi này cũng sẽ được ghi nhận ở các Closure khác.

Closure Scope Chain

Tiếp theo, chúng ta sẽ giải thích tiếp về các ý trong phần mở đầu đã đề cập về 3 phạm vi Closure có thể truy cập bao gồm:

  • Local Scope: phạm vị tự có
  • Outer Functions Scope: phạm vi bên ngoài (phạm vi của hàm cha)
  • Global Scope

Khi lập trình, một trong những sai lầm phổ biến là không nhận ra trường hợp Outer Function là một hàm lồng, dẫn đến việc: phạm vi của Outer Function là phạm vi của Outer Function. Điều này dẫn đến một chuỗi những phạm vi hàm rất hiệu quả.

Để chứng minh cho điều này, hãy cùng Tino Group xem xét một ví dụ sau đây nhé!

// đây là global scope
var e = 10;
function sum(a){
return function(b){
return function(c){
// outer functions scope
return function(d){
// local scope
return a + b + c + d + e;
}
}
}
}
console.log(sum(1)(2)(3)(4)); // log 20
// Bạn cũng có thể viết mà không cần các hàm ẩn danh:
// global scope
var e = 10;
function sum(a){
return function sum2(b){
return function sum3(c){
// outer functions scope
return function sum4(d){
// local scope
return a + b + c + d + e;
}
}
}
}
var sum2 = sum(1);
var sum3 = sum2(2);
var sum4 = sum3(3);
var result = sum4(4);
console.log(result) //log 20

Trong ví dụ trên, bạn có thể thấy một loạt các hàm lồng nhau. Tất cả những hàm này đều có thể truy cập vào phạm vi của những hàm bên ngoài. Với trường hợp này, chúng ta có thể nói rằng: Closure có khả năng truy cập vào tất cả phạm vi của Outer Function.

Cân nhắc về hiệu suất

Đây không phải là một chức năng của Closure trong thực tế mà là một nhắc nhở. Do phần này quá ngắn nên Tino Group xin phép gộp chung vào ví dụ thay vì tách riêng vì nhắc nhở này có liên quan mật thiết đến ví dụ ở trên.

Việc tạo quá nhiều hàm trong một hàm khác khi Closure không cần thiết để giải quyết một tác vụ cụ thể. Lý do là vì Closure sẽ có thể ảnh hưởng tiêu cực đến hiệu suất của script cũng như cả tốc độ xử lý lẫn mức tiêu thụ bộ nhớ!

Vì vậy, bạn hãy cân nhắc thật kỹ nhé!

closure-la-gi

Đến đây, Tino Group hi vọng rằng bạn đã hiểu Closure là gì cũng như hiểu hơn về Closure trong JavaScript thông qua các ví dụ. Chúc bạn sẽ thành công trên con đường lập trình đầy gian nan và thử thách nhé!

Bài viết có tham khảo từ nhiều nguồn: Dev.to, Medium, JavaScript Tutorial, Mozilla Developer, TutorialsTeacher, TopDev,…

Những câu hỏi thường gặp về Closure

Tìm hiểu thêm về Closure ở đâu?

Có khá nhiều tài liệu để bạn tham khảo về Closure nói riêng và JavaScript nói chung như:

Dĩ nhiên, tài liệu của Mozilla Developer sẽ có phần chuẩn chỉnh hơn những tài liệu khác nhưng cũng hơi khó hiểu hơn. Bạn sẽ cần phải có tiếng Anh chuyên ngành hoặc ít nhất tiếng Anh để hiểu bài viết của Mozilla Developer.

Ví dụ thường gặp về Closure khi phỏng vấn xin việc là gì?

Ví dụ này được lấy từ bài viết của Giang Coffee trên Medium, bạn có thể tham khảo, thử tìm ra lỗi sai và khắc phục lỗi này nhé!

for (var i = 0; i < 3; i++) {

setTimeout(function() {

console.log(i);

}, 1000)

}

Cách khắc phục lỗi sai trong ví dụ trên là gì?

Cách thứ nhất: sử dụng let để giải quyết lỗi.

Cách thứ hai: sử dụng thêm nhiều Closure nữa, ví dụ như:

for (var i = 0; i < 3; i++) {

function log(x) {

return function() {

console.log(x);

}

}

setTimeout(log(i), 1000)

}

Dĩ nhiên, trong bài phỏng vấn bạn nhớ được gì bạn cứ thử nhé!

Vì sao trả lời được câu hỏi về Closure nhưng vẫn bị đánh trượt phỏng vấn?

Có vẻ, bạn đã quay lại bài viết này sau một thời gian đi phỏng vấn, dù trả lời được câu hỏi về Closure do nhà tuyển dụng lấy đúng ví dụ trên mạng đúng không nào?

Đừng buồn, có thể vì môi trường không phù hợp, bạn không phù hợp hoặc nhà tuyển dụng thấy mức kỹ năng của bạn vẫn chưa đủ và khá nhiều lý do khác nè.

Chia sẻ một chút thông tin về bạn. Những thông tin này có thể được công khai.

Xem thêm bài viết

Bài viết liên quan

Mục lục

Xem nhiều

giá tốt, chất lượng cao mình rất hài lòng
chất lượng dịch vụ tốt lắm...á
chất lượng dịch vụ rất tốt.
giá tốt, chất lượng cao mình rất hài lòng
Dịch vụ chăm sóc khách hàng tốt
Dùng rất oke nha mọi người
Dịch vụ chăm sóc khách hàng tốt, mình rất hài lòng về dịch vụ của TINOHOST
Đã mua rất nhiều tên miền tại Tinohost. Chất lượng tốt
dịch vụ và chăm sóc khách hàng rất tốt , mình rất thích tinohost , mình đã sử dụng nhiều dịch vụ của tinohost rồi
tuyệt vời chăm sóc khách hàng quá tốt
dịch vụ và chăm sóc khách hàng rất tốt , mình rất thích tinohost , mình đã sử dụng nhiều dịch vụ của tinohost rồi
Quá tốt - Quá xuất sắc và tuyệt
Hỗ trợ nhiệt tình. dịch vụ chất lượng
Đội ngũ support rất nhiệt tình.
Sử dụng dịch vụ của bạn Tinohost 2 3 năm nay chưa khi nào phải thất vọng.
host dùng chất lượng, miền giá rẻ
dịch vụ hỗ trợ rất nhanh, tốc độ hosting tốt
Hộ trợ tốt, nhanh. Tuyệt vời 🥰
tuyệt vời, dịch vụ cực tốt và hỗ trợ siêu nhanh
Làm việc nhanh chóng, giá thành hợp lí.
Hosting rẻ và nhanh thích hợp cho học sinh sinh viên như mình
dịch vu tốt ! Sẽ sử dụng thưởng xuyên !
Mỗi lần cần gì, nhắn Tino là được hỗ trợ ngay. Nên một đứa không biết gì về web như mình cũng tạo được blog. Cơ bản mình chỉ lo viết, mọi thứ có anh IT của Tino lo hết.
Nhìn chung thì Tino xứng đáng là một trong những nhà cung cấp host giá rẻ #1 tại VN. Bên này support khá nhanh và nhiệt tình nên quá trình sử dụng diễn ra tương đối trơn tru.
Chất lượng quá ok so với mức giá. Các SME có thể tham khảo để dựng web nhé.
uy tín chất lượng chuẩn cho 5 sao
Dịch vụ nhanh chóng thanh toán tiện lợi
Dịch vụ nhanh chóng, giá cả hợp lý
Chất lượng phục vụ ok, support khá nhanh chóng và chất lượng gói lớn tốt, gói nhỏ cần tốt hơn.
Dịch vụ tốt, giá cả hợp lý👍
Rất hay, rất tốt, rất hữu ích
Hỗ trợ rất nhanh và nhiệt tình
Chất lượng phục vụ ok, support khá nhanh chóng và chất lượng gói lớn tốt, gói nhỏ cần tốt hơn.
dịch vụ tốt, thanh toán nhanh chống
Hài lòng dịch vụ của tinohost
Sau khi sử dụng dịch vụ của TinoHost. Mình thấy website load nhanh hơn hẳn so với sử dụng ở nhà cung cấp cũ. Giá cả do mình đc mua với giá sale 99% của TinoHost nên rất là rẻ. Gói mình mua là gòi Hosting Bussiness 20GB. Thông số cấu hình cao nên web load khá mượt
Chúc TinoHost phát triển!
domain rẻ, có nhiều gói hữu ích thích hợp cho sinh viên
Hài lòng về dịch vụ và tư vấn
Dịch vụ tốt . Support nhiệt tình
Chất lượng OK
Nhanh chóng
dịch vụ rất tốt
Nhân viên support nhanh, hỗ trợ nhiệt tình, giao dịch tự động nên khá tiện
Đã dùng nhiều dịch vụ tại Tinohost, chất lượng tốt, rất hài lòng ...😀
Sự dụng rất hài lòng với các dịch vụ của tinohost
Dịch vụ tốt, uy tín chất lượng
Tino dịch vụ quá tuyệt vời
Giá rẻ, dịch vụ tốt, hỗ trợ nhanh chóng
dịch vụ rất tốt rất tuyệt vời
Giá hợp lý cho người mới dùng
Mình thấy Tinohost có giao diện thân thiện, dễ đăng ký sử dụng cho người mới tập tành làm web như mình. Hosting hỗ trợ có nhiều lựa chọn về dung lượng và giá cả! Thanh toán qua momo thuận tiện. Recommended!
wed quá ok làm việc nhanh ngọn
Dịch vụ tốt. Khá hài lòng vì support nhiệt tình
Dịch vụ quá tuyệt vời danh cho các bạn
Xin cảm ơn đội ngủ kỹ thuật. Các bạn rất chuyên nghiệp và thân thiện. Tôi sẽ giới thiệu các bạn cho bạn bè của mình.
Dịch vụ hỗ trợ tốt, ổn định, thanh toán dễ dàng.
Mình từng dùng VPS bên Vietel IDC, hay gặp lỗi vặt và bảo trì liên tục. Nhưng Tino thì rất ok
dùng tốt, nhanh, dễ sử dụng
Giao diện đẹp mắt, dễ sử dụng
Đề nghị xem lại vấn đề phục vụ khách hàng (livchat)!
Good. Tốc độ cao. Tùy chỉnh nhiều trên shared hosting.
hosting ngon, giá luôn rẻ, tôi làm code nhưng rất thích sài host tino
Tino cung cấp host rất chuyên nghiệp. Đội ngũ kỹ thuật hỗ trợ rất tận tâm và nhiệt tình. Mình sẽ tiếp tục ủng hộ Tino 🥰.
Rất tuyệt vời🙆🙆🙆🙆🙆🙆🙆🙆🙆
Xét về tầm giá thì TinoHost rất đáng để mua và sử dụng lâu dài.
Dịch vụ chất lượng, ủng hộ 1 năm nay rồi
tuyệt vời quá đi,tuyệt vời quá đi
Tốc độ ổn định, tư vấn nhiệt tình
mới tham gia, mong mọi người hỗ trợ thêm
Tốc độ khá tốt với gói rẻ nhất 9k
Giao dịch nhanh,support nhanh và tận tình,chuyển miền nhanh,Hosting Ok
mua sản phẩm dịch vụ tinhot rất tốt tặng ad 5tr ** luon nè🥰🥰🥰
tinohost
một truong những nơi bán hosting rẻ, chất lượng dành cho anh em nào cần để làm web
mua tại : tinohost.com
mình đã mua 2 tên miền + hosting của Tino Host . quả nhiên hiệu quả SEO cải thiện đáng kể và chứng chỉ bảo mật HTTPS miễn phí của Tino Host cũng ko kém phần quang trọng cho việc SEO website của mình
Tino host là một trong nhà cung cấp tốt nhất mình từng sử dụng. Với ưu đãi khuyến mại nhiều, giá thành rẻ kèm theo đó là sự support tuyệt vời của các admin. Nếu ai chưa lựa chọn được nhà cung cấp cho bản thân mình thì Tinohost sẽ là câu trả lời tốt nhất.
dịch vụ tốt, đội ngũ support nhiệt tình, cảm ơn #tinohost
Uy tín, chất lượng, nhân viên hỗ trợ nhiệt tình
mua 2 domain tại tinohost dùng rất chất lượng
Đã mua 02 domain và hosting tại TinoHost, hài lòng cách tư vấn và chăm sóc khách hàng của TinoHost :)
Giá rẻ cấu hình mạnh, black friday là sự bùng nổ của Tino
Hay web bán tài nguyên rất ngon
dịch vụ tốt, mua luôn host chất lượng cao của công ty nhân dịp blackfriday, cảm ơn #tinohost
Dịch vụ rất tốt, nhân viên tận tình.
Hỗ trợ nhiệt tình nhất trong các nhà cung cấp mih từng dùng. Không những server mạnh, ưu đãi có 1 không 2 mà còn nhiều plugin pro bản quyền đính kèm nữa. Quyết định gắn bó "Lifetime" với tino 😁
Dịch vụ tốt hỗ trợ nhanh chóng
Thích cách tư vấn tận tình và nhanh gọn của Tino mỗi khi có vấn đề trục trặc. Hosting ổn định, giá rẻ tốt lắm nhé mọi người
mình có mua 2 tên msiền của tino, mình rât thích cách tư vấn và chăm sóc khách hàng tại đây. Ngoài ra giá domain khá rẻ, phù hợp cho mọi người. 5 sao
Dịch vụ tốt, support nhiệt tình
tinohost tuyệt vời giá cả hợp lý
domain mua rất rẻ :))))
tốt, chất lượng, hostingok
Hosting tốt, giá cả cạnh tranh
Tuyệt vời , Hosting quá ổn
Chất lượng lắm ạ. Domain mua rẻ nhất thị trường
Dịch vụ tốt và chất lượng
Chất lượng lắm ạ. Domain mua rẻ nhất thị trường
Tino Host dùng quá ngon đi !💥💥💥💥💥
Tôi đã mua domain và hosting của các nhà cung cấp khác rồi, nhưng thực sự thấy không tốt bằng Tino, ngoài ra còn hỗ trợ rất tốt. Cảm ơn tino nhiều!
Next Reviews
CÔNG TY CỔ PHẦN TẬP ĐOÀN TINO
Trụ sở chính: L17-11, Tầng 17, Tòa nhà Vincom Center, Số 72 Lê Thánh Tôn,  Phường Bến Nghé, Q. 1, TP. Hồ Chí Minh

Văn phòng kinh doanh: Số 42 Trần Phú, Phường 4, Quận 5, TP HCM
GPKD số 0315679836 do Sở KH và ĐT TP Hồ Chí Minh cấp
Hotline: 0364 333 333
Góp ý/Phản ánh dịch vụ: 0933 000 886