aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Phỏng vấn JavaScript: vì sao callback trong vòng lặp đều đọc cùng giá trị?

Suong Nguyen by Suong Nguyen
28/10/2026
in Phỏng vấn
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một vòng lặp tạo ba callback nhưng khi gọi lại, cả ba đều trả 3. Nhiều người giải thích ngay bằng setTimeout hoặc event loop. Tuy nhiên, bạn có thể tạo đúng hiện tượng đó mà không dùng timer hay bất kỳ công việc bất đồng bộ nào.

Bài dùng các hàm nhỏ chạy trên Node.js 24.18.1, đối chiếu tài liệu MDN ngày 28/10/2026. Mục tiêu là giải thích callback đang giữ quyền truy cập vào binding nào và binding đó có giá trị gì lúc hàm được gọi.

1. Thử trường hợp dùng var

function makeVarReaders() {
  const readers = [];
  for (var index = 0; index < 3; index++) {
    readers.push(() => index);
  }
  return readers;
}
const varReaders = makeVarReaders();
console.log(varReaders.map(read => read()));

Kết quả là [3, 3, 3]. Callback chưa đọc index lúc được đưa vào mảng. Khi map gọi các hàm, vòng lặp đã kết thúc và binding index chung có giá trị 3.

Trong hàm này, var không tạo một biến index riêng cho mỗi lượt lặp. Ba closure đều truy cập cùng binding. Bạn có thể kiểm tra điều đó bằng cách chỉ ra thời điểm tạo hàm và thời điểm gọi hàm, không cần viện dẫn một hàng đợi timer.

2. Đổi sang let trong khai báo vòng lặp

function makeLetReaders() {
  const readers = [];
  for (let index = 0; index < 3; index++) {
    readers.push(() => index);
  }
  return readers;
}
const letReaders = makeLetReaders();
console.log(letReaders.map(read => read()));

Kết quả là [0, 1, 2]. Khai báo let tại vị trí khởi tạo của vòng for này tạo binding theo từng lượt lặp cho các callback tương ứng. Điều cần giải thích là vị trí khai báo, không chỉ là khẩu quyết “thay var bằng let”.

Nếu ứng viên chỉ nhớ output, hãy hỏi tiếp điều gì xảy ra khi let được khai báo ngoài vòng lặp. Câu hỏi đó giúp phân biệt hiểu scope với việc ghi nhớ một mẹo sửa code.

3. Let ở ngoài vẫn có thể là binding chung

function makeSharedReaders() {
  const readers = [];
  let index = 0;
  for (; index < 3; index++) {
    readers.push(() => index);
  }
  return readers;
}
console.log(makeSharedReaders().map(read => read()));

Kết quả trở lại [3, 3, 3]. Index được khai báo một lần trong scope của hàm, còn vòng for chỉ cập nhật nó. Callback vẫn đọc cùng binding khi được gọi sau vòng lặp.

Đây là lý do nên vẽ scope hoặc nói rõ biến được tạo ở đâu trước khi đề xuất một thay đổi. Từ khóa let có phạm vi block, nhưng không tự biến mọi biến ngoài vòng lặp thành một ảnh chụp giá trị.

4. Một hàm tạo cũng có thể tạo binding riêng

function makeReader(value) {
  return () => value;
}
function makeFactoryReaders() {
  const readers = [];
  for (var index = 0; index < 3; index++) {
    readers.push(makeReader(index));
  }
  return readers;
}
console.log(makeFactoryReaders().map(read => read()));

Kết quả là [0, 1, 2]. Mỗi lần gọi makeReader có parameter binding value riêng. Với các số trong fixture, callback đọc giá trị tương ứng đã được truyền cho lần gọi đó.

Không suy rộng ví dụ thành việc mọi object được truyền vào hàm sẽ được sao chép sâu. Nếu truyền cùng một object rồi sửa nó, bạn vẫn cần phân tích identity và mutation riêng. Closure tạo phạm vi truy cập biến, không phải một công cụ clone dữ liệu.

Liên hệ với callback chạy sau

Timer, handler bấm và một số callback bất đồng bộ có thể làm vấn đề dễ lộ hơn vì chúng được gọi sau khi vòng lặp hoàn tất. Nhưng timer không phải nguyên nhân duy nhất. Bốn snippet trên đều gọi callback đồng bộ sau bước tạo danh sách.

Trong code UI, hãy xác định callback cần ID của từng phần tử hay cần đọc trạng thái mới nhất tại thời điểm chạy. Đôi khi việc đọc một binding thay đổi là đúng ý đồ. Chỉ gọi đó là bug khi hành vi không khớp yêu cầu, rồi chọn vị trí tạo binding phù hợp.

Kiểm tra và cách trả lời phỏng vấn

Viết ra bốn output trước khi chạy. Sau đó đổi số lượt lặp, gọi một callback nhiều lần hoặc chuyển vị trí khai báo biến để kiểm tra mô hình giải thích của bạn. Các ví dụ đã được chạy trong lượt biên tập, không có benchmark hay giả định về độ trễ timer.

Một câu trả lời rõ ràng có ba phần: scope chứa biến, thời điểm tạo closure và thời điểm đọc biến. Khi ba phần đó đã đúng, bạn có thể giải thích cả trường hợp hỏng và hai cách sửa mà không cần học thuộc một kết quả riêng lẻ.

Nguồn tham khảo

  • MDN: Closures và vòng lặp
  • MDN: let
  • MDN: var

Tags: ClosureJavaScriptPhỏng vấn
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Phỏng vấn JavaScript: Object.is khác === thế nào với NaN, +0 và -0?

by Suong Nguyen
27/10/2026
0

Giải thích hai khác biệt về số của Object.is và ===, kiểm tra object identity và tránh nhầm Object.is với so sánh sâu.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

JavaScript sort: vì sao số 10 đứng trước 2 và mảng gốc bị đổi?

by Suong Nguyen
26/10/2026
0

Kiểm tra thứ tự mặc định, hợp đồng comparator, tính ổn định và cách dùng toSorted để giữ mảng gốc khi sắp xếp.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

JavaScript: chọn giá trị mặc định mà không làm mất 0, false và chuỗi rỗng

by Suong Nguyen
25/10/2026
0

Phân biệt toán tử OR, nullish coalescing và optional chaining bằng ví dụ chạy được cùng các trường hợp dễ nhầm khi đọc cấu hình.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Promise.all và allSettled: chờ kết quả không có nghĩa là tự hủy tác vụ

by Suong Nguyen
24/10/2026
0

Chạy ví dụ nhỏ để phân biệt Promise.all, allSettled, thứ tự kết quả và việc hủy công việc khi một promise thất bại.

Next Post
Minh hoạ state thay đổi và làm giao diện React Native cập nhật lại

React Native Switch: cập nhật value từ onValueChange và khóa đúng bằng disabled

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native Switch: cập nhật value từ onValueChange và khóa đúng bằng disabled
  • Phỏng vấn JavaScript: vì sao callback trong vòng lặp đều đọc cùng giá trị?
  • Android ClipboardManager: sao chép text và tránh thông báo trùng từ Android 13

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply