Bạn đang xem : cho mỗi trong mảng js

TL; DR

  • Các cược tốt nhất của bạn thường là

    • vòng lặp for-of (chỉ ES2015 +; spec | MDN ) – đơn giản và async -friendly
        for (const element of theArray) {
          // ... sử dụng `phần tử` ...
      }
       
    • forEach (chỉ ES5 +; spec | MDN ) (hoặc họ hàng của nó một số và như vậy) – not async -friendly (nhưng hãy xem chi tiết)
        theArray.forEach (element = & gt; {
          // ... sử dụng `phần tử` ...
      });
       
    • vòng lặp for kiểu cũ đơn giản – async -friendly
        for (let index = 0; index & lt; theArray.length; ++ index) {
          const element = theArray [index];
          // ... sử dụng `phần tử` ...
      }
       
    • (hiếm khi) for-in với các biện pháp bảo vệ – async -friendly
        for (const propertyName in theArray) {
          if (/*...là thuộc tính phần tử mảng (xem bên dưới) ... * /) {
              const element = theArray [propertyName];
              // ... sử dụng `phần tử` ...
          }
      }
       
  • Một số “không” nhanh:

    • Không sử dụng for-in trừ khi bạn sử dụng nó với các biện pháp bảo vệ hoặc ít nhất biết lý do tại sao nó có thể cắn bạn.
    • Không sử dụng map nếu bạn không sử dụng giá trị trả về của nó .
      (Thật đáng buồn là có người đang dạy map [ spec / MDN ] như thể nó là forEach - nhưng khi tôi viết trên blog của mình , đó không phải là cái dành cho . Nếu bạn không sử dụng mảng mà nó tạo, đừng sử dụng map .)
    • Không sử dụng forEach nếu lệnh gọi lại hoạt động không đồng bộ và bạn muốn forEach đợi cho đến khi công việc đó hoàn thành (vì nó sẽ không).

Nhưng còn rất nhiều điều khác để khám phá, hãy đọc tiếp ...

JavaScript có ngữ nghĩa mạnh mẽ để lặp qua các mảng và các đối tượng giống mảng. Tôi đã chia câu trả lời thành hai phần: Các tùy chọn cho mảng chính hãng và các tùy chọn cho những thứ giống như mảng, chẳng hạn như đối tượng đối số , các đối tượng có thể lặp lại khác (ES2015 +), bộ sưu tập DOM và vân vân.

Được rồi, hãy xem xét các tùy chọn của chúng tôi:

Đối với mảng thực tế

Bạn có năm tùy chọn (hai tùy chọn được hỗ trợ về cơ bản mãi mãi, một tùy chọn khác được thêm bởi ECMAScript 5 ["ES5"] và hai tùy chọn khác được thêm vào ECMAScript 2015 ("ES2015", hay còn gọi là "ES6"):

  1. Sử dụng for-of (sử dụng ngầm định một trình lặp) (ES2015 +)
  2. Sử dụng forEach và có liên quan (ES5 +)
  3. Sử dụng vòng lặp for đơn giản
  4. Sử dụng đúng for-in
  5. Sử dụng trình lặp một cách rõ ràng (ES2015 +)

(Bạn có thể xem các thông số kỹ thuật cũ đó tại đây: ES5 , ES2015 , nhưng cả hai đều đã được thay thế; bản nháp của người chỉnh sửa hiện tại luôn ở ở đây .)

Chi tiết:

1. Sử dụng for-of (sử dụng ngầm định một trình lặp) (ES2015 +)

ES2015 đã thêm trình lặp và tệp lặp vào JavaScript. Mảng có thể lặp lại được (chuỗi, Map s và Set cũng như các bộ sưu tập và danh sách DOM, như bạn sẽ thấy sau này cũng vậy). Các đối tượng có thể lặp lại cung cấp các trình vòng lặp cho các giá trị của chúng. Câu lệnh for-of mới lặp qua các giá trị được trả về bởi một trình lặp:

  const a = ["a", "b", "c"];
for (phần tử const của a) {// Bạn có thể sử dụng `let` thay vì` const` nếu bạn muốn
    console.log (phần tử);
}
// một
// b
// c  

Nó không đơn giản hơn thế! Dưới các lớp phủ, điều đó nhận được một trình lặp từ mảng và lặp qua các giá trị mà trình lặp trả về. Trình vòng lặp do mảng cung cấp cung cấp giá trị của các phần tử mảng, theo thứ tự bắt đầu từ đầu đến cuối.

Lưu ý cách phần tử được xác định phạm vi cho mỗi lần lặp vòng lặp; cố gắng sử dụng phần tử sau khi kết thúc vòng lặp sẽ không thành công vì nó không tồn tại bên ngoài thân vòng lặp.

Về lý thuyết, vòng lặp for-of bao gồm một số lệnh gọi hàm (một để lấy trình lặp, sau đó một để nhận từng giá trị từ nó). Ngay cả khi điều đó đúng, thì không có gì phải lo lắng, các lệnh gọi hàm rất rẻ trong các công cụ JavaScript hiện đại (điều đó làm tôi khó chịu vì forEach [bên dưới] cho đến khi tôi nhìn vào nó; chi tiết ). Nhưng ngoài ra, các công cụ JavaScript sẽ tối ưu hóa các lệnh gọi đó (trong mã quan trọng về hiệu suất) khi xử lý các trình lặp gốc cho những thứ như mảng.

for-of hoàn toàn là async -friendly. Nếu bạn cần thực hiện hàng loạt công việc trong phần thân vòng lặp (không song song), thì một await trong phần thân vòng lặp sẽ đợi lời hứa giải quyết trước khi tiếp tục. Đây là một ví dụ ngớ ngẩn:

  độ trễ chức năng (mili giây) {
    trả lại Lời hứa mới (giải quyết = & gt; {
        setTimeout (giải quyết, mili giây);
    });
}

hàm async showSlowly (thông báo) {
    for (const message of messages) {
        chờ đợi chậm trễ (400);
        console.log (tin nhắn);
    }
}

showSlowly ([
    "Vì vậy, lâu dài và cảm ơn cho tất cả các cá!"
]);
// `.catch` bị bỏ qua vì chúng tôi biết nó không bao giờ từ chối  

Lưu ý cách các từ xuất hiện với độ trễ trước mỗi từ.

Đó là vấn đề của phong cách mã hóa, nhưng for-of là thứ đầu tiên tôi đạt được khi lặp qua bất kỳ thứ gì có thể lặp lại.

2. Sử dụng forEach

có liên quan

Trong bất kỳ môi trường hiện đại nào (không phải IE8) mà bạn có quyền truy cập vào các tính năng của Array do ES5 thêm vào, bạn có thể sử dụng forEach ( spec | MDN ) nếu bạn chỉ xử lý mã đồng bộ (hoặc bạn không cần đợi quá trình không đồng bộ kết thúc trong vòng lặp):

  const a = ["a", "b", "c"];
a.forEach ((phần tử) = & gt; {
    console.log (phần tử);
});  

forEach chấp nhận một hàm gọi lại và tùy chọn một giá trị để sử dụng làm this khi gọi hàm gọi lại đó (không được sử dụng ở trên). Lệnh gọi lại được gọi cho mỗi phần tử trong mảng, theo thứ tự, bỏ qua các phần tử không tồn tại trong mảng thưa thớt. Mặc dù tôi chỉ sử dụng một tham số ở trên, nhưng lệnh gọi lại được gọi với ba đối số: Phần tử cho lần lặp đó, chỉ mục của phần tử đó và một tham chiếu đến mảng bạn đang lặp lại (trong trường hợp hàm của bạn chưa có tiện dụng).

Giống như for-of , forEach có lợi thế là bạn không phải khai báo các biến lập chỉ mục và giá trị trong phạm vi chứa; trong trường hợp này, chúng được cung cấp dưới dạng đối số cho hàm lặp và phạm vi độc đáo đến chỉ lặp đó.

Không giống như for-of , forEach có nhược điểm là nó không hiểu các hàm async đang chờ . Nếu bạn sử dụng hàm async làm lệnh gọi lại, thì forEach không đợi lời hứa của hàm đó giải quyết trước khi tiếp tục. Đây là ví dụ về async từ for-of bằng cách sử dụng forEach - hãy lưu ý cách có độ trễ ban đầu, nhưng sau đó tất cả văn bản xuất hiện ngay lập tức thay vì chờ đợi:

  độ trễ chức năng (mili giây) {
    trả lại Lời hứa mới (giải quyết = & gt; {
        setTimeout (giải quyết, mili giây);
    });
}

hàm async showSlowly (thông báo) {
    // KHÔNG ĐÚNG, không đợi trước khi tiếp tục,
    // không xử lý từ chối lời hứa
    messages.forEach (async message = & gt; {
        chờ đợi chậm trễ (400);
        console.log (tin nhắn);
    });
}

showSlowly ([
    "Vì vậy, lâu dài và cảm ơn cho tất cả các cá!"
]);
// `.catch` bị bỏ qua vì chúng tôi biết nó không bao giờ từ chối  

forEach là hàm "lặp qua tất cả", nhưng ES5 đã định nghĩa một số hàm hữu ích khác "làm việc theo cách của bạn thông qua mảng và làm mọi việc", bao gồm:

  • every ( spec | MDN ) - ngừng lặp lại lần đầu tiên lệnh gọi lại trả về giá trị giả
  • some ( spec | MDN ) - ngừng lặp lại lần đầu tiên lệnh gọi lại trả về giá trị trung thực
  • filter ( spec | MDN ) - tạo một mảng mới bao gồm các phần tử nơi gọi lại trả về một giá trị trung thực, bỏ qua những giá trị không có
  • map ( spec | MDN ) - tạo một mảng mới từ các giá trị được trả về bởi cuộc gọi lại
  • Reduce ( spec | MDN ) - xây dựng giá trị bằng cách gọi lại liên tục , chuyển các giá trị trước đó; xem thông số kỹ thuật để biết chi tiết
  • ReduceRight ( spec | MDN ) - như Reduce , nhưng hoạt động theo thứ tự giảm dần thay vì tăng dần

Như với forEach , nếu bạn sử dụng async hoạt động như một lệnh gọi lại của bạn, không ai trong số đó chờ đợi lời hứa của hàm giải quyết. Điều đó có nghĩa là:

  • Sử dụng lệnh gọi lại hàm async không bao giờ thích hợp với mọi , một số bộ lọc vì chúng sẽ xử lý lời hứa được trả lại như thể nó là một giá trị trung thực; họ không đợi lời hứa kết thúc rồi mới sử dụng giá trị thực hiện.
  • Sử dụng lệnh gọi lại hàm async thường thích hợp với map , nếu mục tiêu là biến một mảng thứ gì đó thành một mảng lời hứa , có lẽ để chuyển đến một trong các hàm kết hợp của hứa hẹn ( Promise.all , Promise.race < / code> , Promise.allSettled hoặc Promise.any ).
  • Việc sử dụng lệnh gọi lại hàm async hiếm khi thích hợp với Reduce hoặc ReduceRight , vì (một lần nữa) lệnh gọi lại sẽ luôn trả về một lời hứa. Nhưng có một thành ngữ xây dựng chuỗi lời hứa từ một mảng sử dụng Reduce ( const Hứa = array.reduce ((p, element) = & gt; p.then (/ *. .. cái gì đó bằng cách sử dụng `element` ... * /)); ), nhưng thường trong những trường hợp đó, vòng lặp for-of hoặc for trong < hàm code> async sẽ rõ ràng hơn và dễ gỡ lỗi hơn.

3. Sử dụng vòng lặp for

đơn giản

Đôi khi, những cách cũ lại là cách tốt nhất:

  const a = ["a", "b", "c"];
for (let index = 0; index & lt; a.length; ++ index) {
    const element = a [index];
    console.log (phần tử);
}  

Nếu độ dài của mảng không thay đổi trong suốt vòng lặp và nó ở mã nhạy cảm với hiệu suất cao, thì một phiên bản phức tạp hơn một chút lấy độ dài lên phía trước có thể nhanh hơn rất nhỏ một chút:

  const a = ["a", "b", "c"];
for (let index = 0, len = a.length; index & lt; len; ++ index) {
    const element = a [index];
    console.log (phần tử);
}  

Và / hoặc đếm ngược:

  const a = ["a", "b", "c"];
for (let index = a.length - 1; index & gt; = 0; --index) {
    const element = a [index];
    console.log (phần tử);
}  

Nhưng với các công cụ JavaScript hiện đại, hiếm khi bạn cần khai thác chút nước cuối cùng đó.

Trước ES2015, biến vòng lặp phải tồn tại trong phạm vi chứa vì var chỉ có phạm vi cấp hàm chứ không phải phạm vi cấp khối. Nhưng như bạn đã thấy trong các ví dụ trên, bạn có thể sử dụng let trong for để phân bổ các biến chỉ trong vòng lặp. Và khi bạn làm điều đó, biến index được tạo lại cho mỗi lần lặp lại vòng lặp, có nghĩa là các bao đóng được tạo trong thân vòng lặp giữ một tham chiếu đến index cho lần lặp cụ thể đó, giải quyết vấn đề cũ "đóng trong vòng lặp":

  // (`NodeList` từ` querySelectorAll` giống như mảng)
const divs = document.querySelectorAll ("div");
for (let index = 0; index & lt; divs.length; ++ index) {
    divs [index] .addEventListener ('click', e = & gt; {
        console.log ("Chỉ số là:" + chỉ mục);
    });
}  
  & lt; div & gt; zero & lt; / div & gt;
& lt; div & gt; một & lt; / div & gt;
& lt; div & gt; hai & lt; / div & gt;
& lt; div & gt; ba & lt; / div & gt;
& lt; div & gt; bốn & lt; / div & gt;  

Ở phần trên, bạn sẽ nhận được "Chỉ mục là: 0" nếu bạn nhấp vào đầu tiên và "Chỉ mục là: 4" nếu bạn nhấp vào cuối cùng. Điều này không hoạt động nếu bạn sử dụng var thay vì let (bạn luôn thấy "Chỉ mục là: 5").

Giống như các vòng lặp for-of , for hoạt động tốt trong các hàm async . Đây là ví dụ trước đó sử dụng vòng lặp for :

  độ trễ chức năng (mili giây) {
    trả lại Lời hứa mới (giải quyết = & gt; {
        setTimeout (giải quyết, mili giây);
    });
}

hàm async showSlowly (thông báo) {
    for (let i = 0; i & lt; messages.length; ++ i) {
        const message = tin nhắn [i];
        chờ đợi chậm trễ (400);
        console.log (tin nhắn);
    }
}

showSlowly ([
    "Vì vậy, lâu dài và cảm ơn cho tất cả các cá!"
]);
// `.catch` bị bỏ qua vì chúng tôi biết nó không bao giờ từ chối  

4. Sử dụng for-in đúng cách

for-in không phải để lặp qua các mảng, nó để lặp qua các tên thuộc tính của một đối tượng. Nó thường hoạt động khi lặp qua các mảng như một sản phẩm phụ của thực tế là các mảng là các đối tượng, nhưng nó không chỉ lặp qua các chỉ mục của mảng mà còn lặp qua tất cả thuộc tính liệt kê của đối tượng (bao gồm cả những thuộc tính kế thừa). (Trước đây, đơn đặt hàng không được chỉ định; bây giờ là [chi tiết trong câu trả lời khác này ], nhưng ngay cả khi đơn đặt hàng đã được chỉ định ngay bây giờ, các quy tắc rất phức tạp, vẫn có ngoại lệ, và dựa vào đơn đặt hàng không phải là phương pháp hay nhất.)

Các trường hợp sử dụng thực tế duy nhất cho for-in trên một mảng là:

  • Đó là một mảng thưa thớt với khoảng trống lớn trong đó hoặc
  • Bạn đang sử dụng các thuộc tính không phải phần tử trên đối tượng mảng và bạn muốn đưa chúng vào vòng lặp

Chỉ xem xét ví dụ đầu tiên đó: Bạn có thể sử dụng for-in để truy cập các phần tử mảng thưa thớt đó nếu bạn sử dụng các biện pháp bảo vệ thích hợp:

  // `a` là một mảng thưa thớt
const a = [];
a [0] = "a";
a [10] = "b";
a [10000] = "c";
for (const name in a) {
    if (Object.hasOwn (a, name) & amp; & amp; // Các lần kiểm tra này là
        /^0$$$$[1-9]\d*$/.test(name) & amp; & amp; // giải thích
        tên & lt; = 4294967294 // bên dưới
       ) {
        const element = a [name];
        console.log (a [tên]);
    }
}  

Lưu ý ba lần kiểm tra:

  1. Rằng đối tượng có thuộc tính riêng của nó theo tên đó (không phải thuộc tính mà nó kế thừa từ nguyên mẫu; kiểm tra này cũng thường được viết là a.hasOwnProperty (name) nhưng ES2022 thêm Object.hasOwn có thể đáng tin cậy hơn) và

  2. Tên là tất cả các chữ số thập phân (ví dụ: dạng chuỗi bình thường, không phải ký hiệu khoa học) và

  3. Giá trị của tên khi bị ép buộc thành một số là & lt; = 2 ^ 32 - 2 (là 4,294,967,294). Con số đó đến từ đâu? Đây là một phần của định nghĩa chỉ mục mảng trong đặc tả . Các số khác (không phải số nguyên, số âm, số lớn hơn 2 ^ 32 - 2) không phải là chỉ số mảng. Lý do nó là 2 ^ 32 - 2 là giá trị chỉ mục lớn nhất thấp hơn 2 ^ 32 - 1 , là giá trị lớn nhất độ dài của mảng có thể có. (Ví dụ: độ dài của một mảng phù hợp với số nguyên không dấu 32 bit.)

... mặc dù đã nói, hầu hết mã chỉ kiểm tra hasOwnProperty .

Tất nhiên, bạn sẽ không làm điều đó trong mã nội tuyến. Bạn sẽ viết một hàm tiện ích. Có lẽ:

  // Hàm tiện ích cho môi trường cổ mà không có `forEach`
const hasOwn = Object.prototype.hasOwnProperty.call.bind (Object.prototype.hasOwnProperty);
const rexNum = / ^ 0 $ | ^ [1-9] \ d * $ /;
function precisionEach (array, callback, thisArg) {
    for (tên const trong mảng) {
        const index = + tên;
        if (hasOwn (a, name) & amp; & amp;
            rexNum.test (tên) & amp; & amp;
            chỉ mục & lt; = 4294967294
           ) {
            callback.call (thisArg, array [name], index, array);
        }
    }
}

const a = [];
a [5] = "năm";
a [10] = "ten";
a [100000] = "một trăm nghìn";
a.b = "ong";

SliceEach (a, (value, index) = & gt; {
    console.log ("Giá trị tại" + chỉ mục + "là" + giá trị);
});  

Giống như for , for-in hoạt động tốt trong các hàm không đồng bộ nếu công việc bên trong nó cần được thực hiện theo chuỗi.

  độ trễ chức năng (mili giây) {
    trả lại Lời hứa mới (giải quyết = & gt; {
        setTimeout (giải quyết, mili giây);
    });
}

hàm async showSlowly (thông báo) {
    for (tên hằng trong tin nhắn) {
        if (messages.hasOwnProperty (name)) {// Hầu như luôn luôn đây là cách kiểm tra duy nhất mọi người làm
            const message = tin nhắn [tên];
            chờ đợi chậm trễ (400);
            console.log (tin nhắn);
        }
    }
}

showSlowly ([
    "Vì vậy, lâu dài và cảm ơn cho tất cả các cá!"
]);
// `.catch` bị bỏ qua vì chúng tôi biết nó không bao giờ từ chối  

5. Sử dụng trình lặp một cách rõ ràng (ES2015 +)

for-of sử dụng trình lặp một cách ngầm định, thực hiện tất cả công việc hướng dẫn cho bạn. Đôi khi, bạn có thể muốn sử dụng một trình lặp một cách rõ ràng. Nó trông như thế này:

  const a = ["a", "b", "c"];
const it = a.values ​​(); // Hoặc `const it = a [Symbol.iterator] ();` nếu bạn thích
để vào;
while (! (entry = it.next ()). done) {
    const element = entry.value;
    console.log (phần tử);
}  

Một trình vòng lặp là một đối tượng phù hợp với định nghĩa Trình lặp lại trong đặc tả. Phương thức next của nó trả về một đối tượng kết quả mới mỗi khi bạn gọi nó. Đối tượng kết quả có một thuộc tính, done , cho chúng tôi biết liệu nó đã xong chưa và một thuộc tính value với giá trị cho lần lặp đó. ( done là tùy chọn nếu nó là false , value là tùy chọn nếu nó là undefined .)

Những gì bạn nhận được cho giá trị khác nhau tùy thuộc vào trình lặp. Trên mảng, trình lặp mặc định cung cấp giá trị của từng phần tử mảng ( "a" , "b" "c" trong ví dụ sớm hơn). Mảng cũng có ba phương thức khác trả về các trình vòng lặp:

  • giá trị () : Đây là bí danh cho phương thức [Symbol.iterator] trả về trình lặp mặc định.
  • keys () : Trả về một trình vòng lặp cung cấp mỗi khóa (chỉ mục) trong mảng. Trong ví dụ trên, nó sẽ cung cấp "0" , sau đó là "1" , rồi "2" (vâng, dưới dạng chuỗi). < / li>
  • entry () : Trả về một trình lặp cung cấp mảng [key, value] .

Vì các đối tượng trình vòng lặp không tiến lên cho đến khi bạn gọi next , chúng hoạt động tốt trong các vòng lặp hàm async . Đây là ví dụ về for-of trước đó bằng cách sử dụng trình lặp một cách rõ ràng:

  độ trễ chức năng (mili giây) {
    trả lại Lời hứa mới (giải quyết = & gt; {
        setTimeout (giải quyết, mili giây);
    });
}

hàm async showSlowly (thông báo) {
    const it = messages.values ​​()
    while (! (entry = it.next ()). done) {
        chịch chịch (400);
        const element = entry.value;
        console.log (phần tử);
    }
}

showSlowly ([
    "Vì vậy, lâu dài và cảm ơn cho tất cả các cá!"
]);
// `.catch` bị bỏ qua vì chúng tôi biết nó không bao giờ từ chối  

Đối với các đối tượng giống mảng

Ngoài mảng true, còn có các đối tượng giống mảng có thuộc tính length và các thuộc tính có tên toàn chữ số: NodeList phiên bản , HTMLCollection instance , đối tượng đối số , v.v. Làm cách nào để chúng tôi lặp lại nội dung của chúng?

Sử dụng hầu hết các tùy chọn ở trên

Ít nhất một số, và có thể là hầu hết hoặc thậm chí tất cả, các phương pháp tiếp cận mảng ở trên áp dụng tốt như nhau cho các đối tượng giống mảng:

  1. Sử dụng for-of (sử dụng ngầm định một trình lặp) (ES2015 +)

    for-of sử dụng trình lặp do đối tượng cung cấp (nếu có). Điều đó bao gồm các đối tượng do máy chủ cung cấp (như bộ sưu tập và danh sách DOM). Ví dụ: các bản sao của HTMLCollection từ các phương thức getElementsByXYZ và các bản sao của NodeList từ querySelectorAll đều hỗ trợ lặp lại. (Điều này được xác định khá tinh tế bởi các đặc tả HTML và DOM. Về cơ bản, bất kỳ đối tượng nào có length và quyền truy cập được lập chỉ mục đều có thể tự động lặp lại. Nó không phải được đánh dấu có thể lặp lại ; chỉ được sử dụng cho các tập hợp, ngoài việc có thể lặp lại, hỗ trợ các giá trị forEach , , các phương thức khóa mục nhập . NodeList thì không; HTMLCollection thì không, nhưng cả hai đều có thể lặp lại.)

    Dưới đây là một ví dụ về lặp qua các phần tử div :

  const divs = document.querySelectorAll ("div");
for (const div của div) {
    div.textContent = Math.random ();
}  
  & lt; div & gt; zero & lt; / div & gt;
& lt; div & gt; một & lt; / div & gt;
& lt; div & gt; hai & lt; / div & gt;
& lt; div & gt; ba & lt; / div & gt;
& lt; div & gt; bốn & lt; / div & gt;  
  1. Sử dụng forEach và có liên quan (ES5 +)

    Các hàm khác nhau trên Array.prototype là "chung chung có chủ đích" và có thể được sử dụng trên các đối tượng giống mảng thông qua Function # call ( spec | MDN ) hoặc Hàm # apply ( spec | MDN ). (Nếu bạn phải đối phó với IE8 hoặc phiên bản cũ hơn [ouch], hãy xem phần "Cảnh báo đối với các đối tượng do máy chủ cung cấp" ở cuối câu trả lời này, nhưng đó không phải là vấn đề với các trình duyệt hiện đại.)

    Giả sử bạn muốn sử dụng forEach trên bộ sưu tập childNodes của Node (là bộ sưu tập HTMLCollection , không có forEach nguyên bản). Bạn sẽ làm điều này:

      Array.prototype.forEach.call (node.childNodes, (child) = & gt; {
        // Làm gì đó với `child`
    });
     

    (Tuy nhiên, lưu ý rằng bạn chỉ có thể sử dụng for-of trên node.childNodes .)

    Nếu bạn định làm điều đó nhiều, bạn có thể muốn lấy một bản sao của tham chiếu hàm vào một biến để sử dụng lại, ví dụ:

      // (Đây có lẽ là tất cả trong một mô-đun hoặc một số chức năng xác định phạm vi)
    const forEach = Array.prototype.forEach.call.bind (Array.prototype.forEach);
    
    // Sau đó ...
    forEach (node.childNodes, (child) = & gt; {
        // Làm gì đó với `child`
    });
     
  2. Sử dụng vòng lặp for đơn giản

    Có lẽ rõ ràng, một vòng lặp for đơn giản phù hợp với các đối tượng dạng mảng.

  3. Sử dụng trình lặp một cách rõ ràng (ES2015 +)

    Xem # 1.

Bạn có thể thoát khỏi for-in (với các biện pháp bảo vệ), nhưng với tất cả các tùy chọn thích hợp hơn này, không có lý do gì để thử.

Tạo một mảng đúng

Khi khác, bạn có thể muốn chuyển đổi một đối tượng giống mảng thành một mảng thực. Làm điều đó dễ dàng một cách đáng ngạc nhiên:

  1. Sử dụng Array.from

    Array.from (spec) | (MDN) (ES2015 +, nhưng dễ được điền đầy đủ) tạo một mảng từ một đối tượng giống mảng, tùy chọn chuyển các mục nhập thông qua một hàm ánh xạ trước. Vì vậy:

      const divs = Array.from (document.querySelectorAll ("div"));
     

    ... lấy NodeList từ querySelectorAll và tạo một mảng từ đó.

    Chức năng ánh xạ rất hữu ích nếu bạn định lập bản đồ nội dung theo một cách nào đó. Ví dụ: nếu bạn muốn nhận một mảng tên thẻ của các phần tử với một lớp nhất định:

      // Sử dụng thông thường (với hàm mũi tên):
    const divs = Array.from (document.querySelectorAll (". some-class"), element = & gt; element.tagName);
    
    // Hàm truyền thống (vì `Array.from` có thể được điền đầy đủ):
    var divs = Array.from (document.querySelectorAll (". some-class"), function (element) {
        return element.tagName;
    });
     
  2. Sử dụng cú pháp lây lan ( ... )

    Cũng có thể sử dụng cú pháp lây lan của ES2015. Giống như for-of , điều này sử dụng iterator được cung cấp bởi đối tượng (xem # 1 trong phần trước):

      const trueArray = [... iterableObject];
     

    Ví dụ: nếu chúng ta muốn chuyển đổi một NodeList thành một mảng true, với cú pháp lây lan, điều này trở nên khá ngắn gọn:

      const divs = [... document.querySelectorAll ("div")];
     
  3. Sử dụng phương thức slice của mảng

    Chúng ta có thể sử dụng phương thức slice cho mảng, giống như các phương thức khác được đề cập ở trên là "có chủ đích chung chung" và do đó, có thể được sử dụng với mảng -đối tượng giống như thế này:

      const trueArray = Array.prototype.slice.call (arrayLikeObject);
     

    Ví dụ: nếu chúng ta muốn chuyển đổi NodeList thành một mảng true, chúng ta có thể thực hiện điều này:

      const divs = Array.prototype.slice.call (document.querySelectorAll ("div"));
     

    (Nếu bạn vẫn phải xử lý IE8 [ouch], sẽ không thành công; IE8 đã không cho phép bạn sử dụng các đối tượng do máy chủ cung cấp dưới dạng this như vậy.)

Cảnh báo đối với các đối tượng do máy chủ cung cấp

Nếu bạn sử dụng các hàm Array.prototype với các đối tượng giống mảng do máy chủ cung cấp (ví dụ: bộ sưu tập DOM và các bộ sưu tập đó được cung cấp bởi trình duyệt chứ không phải công cụ JavaScript), thì các trình duyệt lỗi thời như IE8 đã không ' không nhất thiết phải xử lý theo cách đó, vì vậy nếu bạn phải hỗ trợ chúng, hãy đảm bảo thử nghiệm trong môi trường mục tiêu của bạn. Nhưng nó không phải là một vấn đề với các trình duyệt mơ hồ hiện đại. (Đối với môi trường không có trình duyệt, tự nhiên nó sẽ phụ thuộc vào môi trường.)


Xem thêm những thông tin liên quan đến chủ đề cho mỗi trong mảng js

How to Flatten an Array in JavaScript

  • Tác giả: Read Write Exercise
  • Ngày đăng: 2019-01-02
  • Đánh giá: 4 ⭐ ( 7045 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: This is a brief run through on how to flatten an array in JavaScript.

    This is purely for educational purposes as you'll likely want to use something like this in your normal code https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

    📬 SUBSCRIBE: https://www.youtube.com/channel/UCPGv2tVqEt6iBFnnMTjnRBA?sub_confirmation=1

    Code link: https://github.com/bradydowling/youtube-code/blob/master/flatten-array/finish.js

    In this playlist
    Part 1: https://www.youtube.com/watch?v=dDQgT7vyhPQ
    Part 2: https://www.youtube.com/watch?v=g6580pYHFd4
    Part 3: https://www.youtube.com/watch?v=SZKkK908KSw
    Part 4: https://www.youtube.com/watch?v=rude5xbrc8E

Các phương thức của mảng trong JavaScript

  • Tác giả: completejavascript.com
  • Đánh giá: 3 ⭐ ( 6987 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Có rất nhiều phương thức của mảng trong JavaScript. Nhờ đó, việc xử lý mảng trở nên dễ dàng hơn. Sau đây là các phương thức xử lý mảng phổ biến nhất.

Làm việc với mảng (Array) trong Javascript

  • Tác giả: phambinh.net
  • Đánh giá: 3 ⭐ ( 9475 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Tổng hợp các phương thức, thuộc tính làm việc với mảng trong JavaScript. Các hàm xử mảng trong JavaScript, các hàm xử lý array trong JavaScript.

Khai báo và duyệt mảng trong javascript

  • Tác giả: mylop.edu.vn
  • Đánh giá: 5 ⭐ ( 9694 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Trong bài này mình sẽ hướng dẫn cách khai báo mảng và duyệt mảng trong Javascript, bằng cách sử dụng vòng lặp for, while và foreach để lặp.

Một số hàm hữu ích để xử lý mảng trong Javascript

  • Tác giả: viblo.asia
  • Đánh giá: 3 ⭐ ( 2404 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Đôi khi chúng ta bị cuốn theo những Framework, lib... được xây dững sẵn mà quên đi những kiến thức căn bản có thể đã từng tồn tại trong đầu của chúng ta.

Tính tổng các phần tử trong mảng javascript

  • Tác giả: freetuts.net
  • Đánh giá: 5 ⭐ ( 3758 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Cách tính tổng các phần tử trong mảng javascript, bằng cách sử dụng vòng lặp và các hàm xử lý mảng có sẵn trong js như ham map - hàm reduce - hàm reduce right

JavaScript: vòng lặp forEach trong mảng

  • Tác giả: www.daipho.com
  • Đánh giá: 5 ⭐ ( 9364 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Trong JavaScript, Phương thức forEach duyệt qua từng phần tử trong mảng theo thứ tự tăng dần và thực thi một hàm cho mỗi phần tử đó. Phương thức này sẽ

Xem thêm các bài viết khác thuộc chuyên mục: Kiến thức lập trình

Xem Thêm  Cách tạo màu nền trong suốt trong CSS - Làm thế nào để làm cho nền hộp văn bản trong suốt trong css

By ads_php