Làm cách nào để vượt qua vòng lặp JavaScript?
Khi bạn đính kèm nhiều sự kiện nhấp chuột vào các phần tử, chẳng hạn như các nút bên trong vòng lặp for, sự kiện nhấp chuột sẽ luôn cung cấp cho chúng tôi giá trị chỉ mục cuối cùng bất kể nút nào được nhấn Show
Đây là một trong những vấn đề phổ biến mà các nhà phát triển gặp phải khi bắt đầu học JavaScript Đến cuối bài viết này, bạn sẽ biết nguyên nhân gây ra sự cố này và một số cách khắc phục sự cố Đoạn mã gây ra sự cốNhư bạn có thể thấy, trang HTML có một phần tử 0 với một 1 được gọi là 2
Đây là nơi tôi đã thêm năm nút một cách linh hoạt bằng cách sử dụng vòng lặp 3 trong mã JavaScript bên dưới
Tôi cũng đã đính kèm một sự kiện nhấp chuột vào một phần tử nút và nối nó vào phần tử 4 trên mỗi lần lặp lạiNếu tôi chạy mã ở giai đoạn này, tôi sẽ nhận được giá trị là 5 bất kể nút nào được nhấn Trước khi hiểu chuyện gì đang xảy ra ở đây… chúng ta cần biết… hoisting là gì
cẩuTheo mặc định, một biến được khai báo với từ khóa 5 là phạm vi chức năng chứ không phải phạm vi khốiVì vậy, bất kỳ biến nào được khai báo bên trong một hàm, bất kể độ sâu của nó, sẽ được chuyển lên trên cùng và có thể truy cập được ở bất kỳ đâu bên trong hàm đó Mặt khác, nếu một biến được khai báo bên ngoài một hàm, nó sẽ trở thành một biến có phạm vi toàn cầu và chúng ta có thể truy cập nó ở bất kỳ đâu trong ứng dụng vì nó thuộc về đối tượng cửa sổ (chỉ dành cho trình duyệt) Hành vi đó được gọi là Hoisting Biến const buttonsContainer = document.getElementById("buttonsContainer"); for (var i = 0; i < 5; i++) { const button = document.createElement("button"); button.innerText = i; button.addEventListener("click", function() { console.log(i) }) buttonsContainer.appendChild(button); } 6 Luôn Có Chỉ Số Cuối CùngBây giờ hãy xem điều gì xảy ra với đoạn mã trên Biến 6 được khai báo với từ khóa 5 sẽ tự động được chuyển lên đầu trang vì nó không được khai báo bên trong hàm nên nó trở thành biến toàn cục do hoistingVì vậy, biến 6 rõ ràng không nằm trong phạm vi của vòng lặp 3, nhưng nó nằm trong phạm vi toàn cầu và nó bị ràng buộc với cùng một biến bên ngoài hàm gọi lại trên mỗi lần lặpVào thời điểm vòng lặp 3 đi đến lần lặp cuối cùng, biến 6 sẽ kết thúc việc giữ giá trị chỉ số cuối cùng. Đó là lý do tại sao đầu ra sẽ luôn là chỉ mục cuối cùng, trong trường hợp của tôi là 5
const buttonsContainer = document.getElementById("buttonsContainer"); for (var i = 0; i < 5; i++) { const button = document.createElement("button"); button.innerText = i; button.addEventListener("click", function() { console.log(i) }) buttonsContainer.appendChild(button); } 6 Là Biến Toàn cụcTôi sẽ vào console log biến i bên ngoài vòng lặp for
Bạn sẽ nhận được 5 trong bảng điều khiển trình duyệt ngay khi mã kết thúc thực thi mà không cần nhấp vào bất kỳ nút nào Điều này chứng tỏ rằng biến 6 có phạm vi toàn cầuBây giờ chúng ta đã biết thủ phạm chính là biến 6 được khai báo với từ khóa 5Hãy xem xét một số giải pháp để khắc phục nó Giải pháp số 1. Khép kínChúng ta có thể sử dụng bao đóng để thay đổi phạm vi của biến 6 giúp các hàm có thể có biến riêng tưSử dụng bao đóng, chúng ta có thể lưu riêng chỉ mục vòng lặp trên mỗi hàm gọi lại
Hãy xem điều đó trong hành động Đầu tiên, xác định bao đóng bằng cách sử dụng dấu ngoặc đơn mở và đóng 8 bên trong vòng lặp 3Sau đó, khai báo một hàm ẩn danh nhận tham số chỉ số Sau đó, chuyển biến toàn cục 6 vào bao đóng với tập cuối cùng của (), gọi bao đóng một lần trên mỗi lần lặpĐiều này còn được gọi là Biểu thức hàm được gọi ngay lập tức (IIFE), đây là một cách để khai báo các bao đóng
Vì vậy, đoạn mã trên nắm bắt giá trị của biến 6 tại mỗi lần lặp lại và chuyển nó thành một đối số cho hàm tạo phạm vi cục bộGiờ đây, mỗi hàm có phiên bản riêng của biến chỉ mục sẽ không thay đổi khi các hàm được tạo trong vòng lặp đó Hàm đóng này bảo toàn giá trị của ___________6 (biến riêng tư) duy nhất cho mỗi trình xử lý sự kiện để mỗi người có quyền truy cập vào giá trị của riêng mình Khi bạn nhấp vào bất kỳ nút nào sau khi vòng lặp for kết thúc, hàm gọi lại thích hợp sẽ được thực thi với giá trị chỉ mục chính xác Tôi hy vọng điều đó đúng
Giải pháp số 2. Đóng chức năng bên ngoài Trả về chức năng bên trongNgoài ra, bạn có thể trả về một hàm bên trong hàm gọi lại đóng
Trong ví dụ trước, toàn bộ mã trình xử lý sự kiện bấm nút được bao bọc bằng bao đóng Trong ví dụ này, chỉ chức năng gọi lại bấm nút được bao bọc bằng một bao đóng Hàm bên ngoài sẽ được thực thi trên mỗi lần lặp lại và biến 6 (toàn cục) được truyền dưới dạng đối số trong trình gọi hàm bên ngoài như thế này (i)Hàm bên trong sẽ được trả về trên mỗi lần lặp và được đính kèm với sự kiện nhấp chuột với giá trị chỉ mục duy nhất Trong bao đóng, các hàm bên trong có thể có quyền truy cập vào các biến được khai báo bên ngoài nó ngay cả sau khi hàm bên ngoài được trả về Giải pháp số 3. Sử dụng for (var i = 0; i < 5; i++) { var button = document.createElement("button"); button.innerText = i; (function(index){ button.addEventListener("click", function() { console.log(index) }) })(i) buttonsContainer.appendChild(button); } console.log(i);4 Thay vì const buttonsContainer = document.getElementById("buttonsContainer"); for (var i = 0; i < 5; i++) { const button = document.createElement("button"); button.innerText = i; button.addEventListener("click", function() { console.log(i) }) buttonsContainer.appendChild(button); } 3Điều này sẽ rất tuyệt nếu bạn có một mảng các mục và bạn chỉ cần chạy phương thức 6 trên đó, nhưng nó không được khuyến nghị khi hoạt động không đồng bộ đang diễn ra trên mỗi lần lặpTheo mặc định, vòng lặp 4 cung cấp một cách rõ ràng và tự nhiên để nhận hàm đóng gọi lại riêng biệt trên mỗi lần lặp
Nó hoạt động mà không cần thêm bất kỳ hàm bao bọc bổ sung nào, sạch hơn ví dụ trước
Giải pháp số 4. Sử dụng for (var i = 0; i < 5; i++) { var button = document.createElement("button"); button.innerText = i; (function(index){ button.addEventListener("click", function() { console.log(index) }) })(i) buttonsContainer.appendChild(button); } console.log(i);8 thay vì const buttonsContainer = document.getElementById("buttonsContainer"); for (var i = 0; i < 5; i++) { const button = document.createElement("button"); button.innerText = i; button.addEventListener("click", function() { console.log(i) }) buttonsContainer.appendChild(button); } 5Trong ES6, chúng tôi có các từ khóa 8 và 1 nằm trong phạm vi khối trái ngược với 5 nằm trong phạm vi chức năng. Nói cách khác, 8 và 1 cũng được nâng lên như var nhưng chúng không được khởi tạo với giá trị mặc địnhVì vậy, sử dụng từ khóa 8 liên kết hàm gọi lại mới với giá trị chỉ mục trên mỗi lần lặp thay vì sử dụng lặp đi lặp lại cùng một tham chiếuĐể khắc phục điều đó, hãy thay đổi 5 thành 8 từ mã ban đầu và nó hoạt động
Đây là cách nhanh nhất để khắc phục sự cố sự kiện nhấp chuột trong một vòng lặp Tuy nhiên, một vấn đề với phương pháp này là phải cẩn thận với khả năng tương thích ngược của trình duyệt vì đây là một phần của tính năng ES6
Khai báo chức năng gọi lại bên ngoài vòng lặpĐôi khi chúng ta muốn khai báo riêng một hàm gọi lại với một tên thay vì sử dụng một hàm ẩn danh nội tuyến bên trong hàm tạo addEventListener Vì vậy, hãy khai báo một hàm gọi lại được gọi là hàm buttonClicked() và gọi nó bên trong hàm tạo addEventListener mà không cần bất kỳ dấu ngoặc đơn nào Theo mặc định, đối tượng 8 được truyền vào hàm buttonClicked()Sau đó, tôi có thể dễ dàng truy cập vào bất kỳ thông tin nào về phần tử đã chọn bằng đối tượng 8
Điều gì xảy ra nếu tôi muốn chuyển trực tiếp một giá trị cho hàm gọi lại dưới dạng đối số?
Điều này rất giống với Giải pháp số 2 Khi chúng ta chuyển một giá trị cho 0, nó sẽ trở thành một bao đóng (IIFE) là hàm bên ngoài và chạy trên mỗi lần lặpHàm bên trong sẽ được trả về trên mỗi lần lặp và được đính kèm với sự kiện nhấp chuột với giá trị chỉ mục Và… điều đó sẽ làm nên điều kỳ diệu
Phần kết luậnTrong bài viết này, bạn đã học cách khắc phục sự cố phát sinh khi bạn đính kèm các sự kiện nhấp chuột bên trong vòng lặp 3 theo một số cáchPhạm vi trong JavaScript là một chủ đề lớn và tôi vẫn đang tìm hiểu về Đóng cửa và các khái niệm khác trong JavaScript Nếu bạn có bất kỳ đề xuất, phản hồi hoặc nếu bất cứ điều gì không rõ ràng trong bài viết này, vui lòng liên hệ với tôi bằng cách nhận xét bên dưới Vòng lặp for được thực thi như thế nào trong JavaScript?Để thực hiện vòng lặp này, điều kiện Bắt đầu được kiểm tra. Đây thường là giá trị ban đầu mà quá trình đếm sẽ bắt đầu. Tiếp theo, Điều kiện được kiểm tra; . Nếu thử nghiệm cho kết quả đúng, thì Biểu thức được sử dụng để sửa đổi vòng lặp và Câu lệnh được thực thi
Làm cách nào để tiếp tục một vòng lặp trong JavaScript?Câu lệnh continue dùng để bỏ qua bước lặp hiện tại của vòng lặp và luồng điều khiển của chương trình chuyển sang bước lặp tiếp theo. Cú pháp của câu lệnh continue là. tiếp tục [nhãn];
Làm cách nào để thoát khỏi vòng lặp JavaScript?Từ khóa break cung cấp luồng điều khiển từ câu lệnh switch. Tất cả các loại vòng lặp có thể được đặt bên trong nhau hoặc “lồng nhau. ” Để thoát khỏi các vòng lặp lồng nhau, hãy gắn nhãn cho các vòng lặp và chuyển tên nhãn cho từ khóa ngắt . Điều này hoạt động bất kể có bao nhiêu cấp độ lồng nhau tồn tại.
Làm cách nào để bỏ qua một lần lặp cho vòng lặp JavaScript?Cú pháp. break tên nhãn; tên nhãn tiếp tục; Chỉ có thể sử dụng câu lệnh continue (có hoặc không có tham chiếu nhãn) để bỏ qua . |