Cái này gọi là Closure nhé bạn 
Sử dụng closure bên trong 1 vòng lặp
Closure là 1 chủ đề thường thấy trong các buổi phỏng vấn JavaScript, nó giúp người phỏng vấn đánh giá bạn thành thục ngôn ngữ đến đâu, bạn biết implement closure hay không.
Về cơ bản, closure là 1 hàm nội truy cập đến các biến bên ngoài phạm vi của nó. Closure có thể được sử dụng để implement privacy và tạo ra các function factory. Một câu hỏi phỏng vấn thường thấy về việc sử dụng closure sẽ có kiểu thế này:
Viết 1 function lặp qua 1 danh sách các số dạng integer và in ra index của mỗi giá trị sau thời gian chờ 3s.
Dưới đây là cách tôi hay thấy khi mọi người giải quyết bài toán này (thực ra là sai):
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('The index of this number is: ' + i);
}, 3000);
}
Nếu bạn chạy đoạn code trên, output bạn nhận được sẽ luôn là 4, mặc dù ta mong rằng output sẽ phải là 0, 1, 2, 3 sau mỗi 3s.
Tại sao lại như thế? Để hiểu rõ lý do, đương nhiên bạn cần nắm vững kiến thức về closure của JavaScript, bởi vì người phỏng vấn đang kiểm tra bạn về nó cơ mà!
Lý do là bởi vì hàm setTimeout sẽ tạo ra 1 function (closure) có thể truy cập phạm vi bên ngoài nó, vòng loop sẽ chứa index i. Sau 3s, hàm được thực thi và nó sẽ log ra giá trị của i, là giá trị cuối cùng của vòng lặp (4).
Có 1 số cách để viết hàm đúng. Dưới đây tôi sẽ chỉ nêu ra 2 cách:
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
// pass in the variable i so that each function
// has access to the correct index
setTimeout(function(i_local) {
return function() {
console.log('The index of this number is: ' + i_local);
}
}(i), 3000);
}
const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
// using the ES6 let syntax, it creates a new binding
// every single time the function is called
// read more here: http://exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads
setTimeout(function() {
console.log('The index of this number is: ' + i);
}, 3000);
}
Ref: https://www.topitworks.com/blogs/phong-van-javascript/