Mảng cung cấp rất nhiều phương thức. Để làm cho mọi thứ dễ dàng hơn, trong chương này, chúng được chia thành các nhóm.

Thêm / xóa các mục

Chúng ta đã biết các phương pháp thêm và xóa các mục từ đầu hoặc cuối:

  • arr.push(...items) – thêm các mục vào cuối,
  • arr.pop() – trích xuất một mục từ cuối,
  • arr.shift() – trích xuất một mục từ đầu,
  • arr.unshift(...items) – thêm các mục vào đầu.

Dưới đây là một vài cái khác.

splice

Làm thế nào để xóa một phần tử từ mảng?

Các mảng là các đối tượng, vì vậy chúng ta có thể thử sử dụng delete:

let arr = ["I", "go", "home"];

delete arr[1]; // remove "go"

alert( arr[1] ); // undefined

// now arr = ["I",  , "home"];
alert( arr.length ); // 3

Phần tử đã bị xóa, nhưng mảng vẫn có 3 phần tử, chúng ta có thể thấy điều đó arr.length == 3.

Điều đó là tự nhiên, bởi vì delete obj.keyloại bỏ một giá trị bởi key. Đó là tất cả những gì nó làm. Tốt cho các đối tượng. Nhưng đối với mảng, chúng ta thường muốn các phần tử còn lại dịch chuyển và chiếm vị trí tự do. Chúng tôi hy vọng sẽ có một mảng ngắn hơn bây giờ.

Vì vậy, nên sử dụng các phương pháp đặc biệt.

Phương thức arr.splice(start) là một con dao cho các mảng. Nó có thể làm mọi thứ: chèn, loại bỏ và thay thế các mục.




Cú pháp là:

arr.splice(index[, deleteCount, elem1, ..., elemN])

Nó bắt đầu từ vị trí index: loại bỏ deleteCountcác yếu tố và sau đó chèn elem1, ..., elemNvào vị trí của chúng. Trả về mảng các phần tử bị loại bỏ.

Phương pháp này dễ nắm bắt bằng các ví dụ.

Hãy bắt đầu với việc xóa:

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]

Dễ thôi phải không? Bắt đầu từ chỉ mục 1nó loại bỏ 1yếu tố.

Trong ví dụ tiếp theo, chúng tôi loại bỏ 3 yếu tố và thay thế chúng bằng hai yếu tố còn lại:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]

Ở đây chúng ta có thể thấy rằng splicetrả về mảng các phần tử bị loại bỏ:

let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements

Các phương thức splice cũng có thể chèn các yếu tố. Cho rằng chúng ta cần phải đặt deleteCountthành 0:

let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"

Chỉ số được phép

Ở đây và trong các phương thức mảng khác, các chỉ mục tiêu cực được cho phép. Họ chỉ định vị trí từ cuối mảng, như ở đây:




let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5

slice

Phương thức Array.slice đơn giản hơn nhiều so với arr.splice.

Cú pháp là:

arr.slice([start], [end])

Nó trả về một bản sao mới cho tất cả các mục từ chỉ mục startđến end(không bao gồm end). Cả hai startendcó thể âm, trong trường hợp đó, vị trí từ cuối mảng được giả sử.

Nó tương tự như một phương thức chuỗi str.slice, nhưng thay vì các chuỗi con, nó tạo ra các chuỗi con.

Ví dụ:

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)

Chúng ta cũng có thể gọi nó mà không cần đối số: arr.slice()tạo một bản sao của arr. Điều đó thường được sử dụng để có được một bản sao cho các biến đổi tiếp theo mà không ảnh hưởng đến mảng ban đầu.

concat

Phương thức Array.concat tạo ra một mảng mới bao gồm các giá trị từ các mảng khác và các mục bổ sung.

Cú pháp là:

arr.concat(arg1, arg2...)

Nó chấp nhận bất kỳ số lượng đối số hoặc giá trị.

Kết quả là một mảng mới chứa các mục từ arr, sau đó arg1, arg2v.v.




Nếu một đối số argNlà một mảng, thì tất cả các phần tử của nó được sao chép. Mặt khác, chính đối số được sao chép.

Ví dụ:

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let arr = [1, 2];

// create an array from: arr and [3,4]
alert( arr.concat([3, 4]) ); // 1,2,3,4

// create an array from: arr and [3,4] and [5,6]
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6

// create an array from: arr and [3,4], then add values 5 and 6
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6

Thông thường, nó chỉ sao chép các phần tử từ mảng. Các đối tượng khác, ngay cả khi chúng trông giống như mảng, được thêm vào như một tổng thể:

let arr = [1, 2];

let arrayLike = {
  0: "something",
  length: 1
};

alert( arr.concat(arrayLike) ); // 1,2,[object Object]

Nhưng nếu một đối tượng giống như mảng có một thuộc tính đặc biệt Symbol.isConcatSpreadable, thì nó được coi là một mảng bằng cách concat: các phần tử của nó được thêm vào:

let arr = [1, 2];

let arrayLike = {
  0: "something",
  1: "else",
  [Symbol.isConcatSpreadable]: true,
  length: 2
};

alert( arr.concat(arrayLike) ); // 1,2,something,else

Lặp lại: forEach

Các phương thức arr.forEach cho phép để chạy một hàm cho mọi phần tử của mảng.

Cú pháp:

arr.forEach(function(item, index, array) {
  // ... do something with item
});

Ví dụ, điều này cho thấy từng phần tử của mảng:

// for each element call alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);

Và code này chi tiết hơn về vị trí của chúng trong mảng:

["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
  alert(`${item} is at index ${index} in ${array}`);
});

Kết quả của hàm (nếu nó trả về bất kỳ) sẽ bị loại bỏ và bỏ qua.

Tìm kiếm trong mảng

Bây giờ hãy bao gồm các phương pháp tìm kiếm trong một mảng.




indexOf/lastIndexOf and includes

Các phương thức arr.indexOf, arr.lastIndexOf and arr.includes có cùng một cú pháp và về cơ bản giống như các đối tác chuỗi của chúng, nhưng hoạt động trên các mục thay vì các ký tự:

  • arr.indexOf(item, from)– tìm kiếm itembắt đầu từ chỉ mục fromvà trả về chỉ mục nơi nó được tìm thấy, nếu không -1.
  • arr.lastIndexOf(item, from) – giống nhau, nhưng tìm kiếm từ phải sang trái.
  • arr.includes(item, from)– tìm kiếm itembắt đầu từ chỉ mục from, trả về truenếu tìm thấy.

Ví dụ:

let arr = [1, 0, false];

alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // true

Lưu ý rằng các phương thức sử dụng so sánh ===. Vì vậy, nếu chúng ta tìm kiếm false, nó tìm thấy chính xác falsevà không phải là số không.

Nếu chúng ta muốn kiểm tra để đưa vào và không muốn biết chỉ số chính xác, thì nên arr.includesưu tiên.

Ngoài ra, một điểm khác biệt rất nhỏ includeslà nó xử lý chính xác NaN, không giống như indexOf/lastIndexOf:

const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (should be 0, but === equality doesn't work for NaN)
alert( arr.includes(NaN) );// true (correct)

tfind and findIndex

Hãy tưởng tượng chúng ta có một mảng các đối tượng. Làm thế nào để chúng ta tìm thấy một đối tượng với điều kiện cụ thể?

Ở đây phương thức arr.find(fn) có ích.

Cú pháp là:

let result = arr.find(function(item, index, array) {
  // if true is returned, item is returned and iteration is stopped
  // for falsy scenario returns undefined
});

Hàm được gọi cho các phần tử của mảng, lần lượt từng phần một:

  • item là yếu tố.
  • index là chỉ số của nó.
  • array là mảng chính nó.

Nếu nó trở lại true, tìm kiếm bị dừng lại, itemđược trả lại. Nếu không tìm thấy gì, undefinedđược trả lại.




Ví dụ: chúng tôi có một mảng người dùng, mỗi người có các trường idname. Hãy tìm một người có id == 1:

let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];

let user = users.find(item => item.id == 1);

alert(user.name); // John

Trong các mảng thực tế của các đối tượng là một điều phổ biến, vì vậy find là phương thức này rất hữu ích.

Lưu ý rằng trong ví dụ chúng ta cung cấp cho hàm find item => item.id == 1với một đối số. Đó là điển hình, các đối số khác của hàm này hiếm khi được sử dụng.

Các arr.findIndex phương pháp cơ bản là giống nhau, nhưng nó sẽ trả về chỉ số nơi các phần tử đã được tìm thấy thay vì các yếu tố bản thân và -1được trả về khi không có gì được tìm thấy.

filter

Các findphương pháp tìm kiếm một (đầu tiên) yếu tố duy nhất mà làm cho chức năng quay trở lại true.

Nếu có thể có nhiều, chúng ta có thể sử dụng arr.filter(fn).

Cú pháp tương tự find, nhưng filtertrả về một mảng của tất cả các phần tử phù hợp:

let results = arr.filter(function(item, index, array) {
  // if true item is pushed to results and the iteration continues
  // returns empty array if nothing found
});

Ví dụ:

let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];

// returns array of the first two users
let someUsers = users.filter(item => item.id < 3);

alert(someUsers.length); // 2

Chuyển đổi một mảng

Hãy chuyển sang các phương thức biến đổi và sắp xếp lại một mảng.

map

Các phương thức arr.map là một trong những nhất hữu ích và thường được sử dụng.




Nó gọi hàm cho từng phần tử của mảng và trả về mảng kết quả.

Cú pháp là:

let result = arr.map(function(item, index, array) {
  // returns the new value instead of item
});

Chẳng hạn, ở đây chúng ta biến đổi từng phần tử thành độ dài của nó:

let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6

sắp xếp (fn)

Lệnh gọi tới arr.sort() sắp xếp mảng tại chỗ, thay đổi thứ tự phần tử của nó.

Nó cũng trả về mảng đã sắp xếp, nhưng giá trị trả về thường bị bỏ qua, vì arrchính nó đã được sửa đổi.

Ví dụ:

let arr = [ 1, 2, 15 ];

// the method reorders the content of arr
arr.sort();

alert( arr );  // 1, 15, 2

Bạn có nhận thấy điều gì kỳ lạ trong kết quả không?

Trật tự trở thành 1, 15, 2. Sai. Nhưng tại sao?

Các mục được sắp xếp theo chuỗi theo mặc định.

Theo nghĩa đen, tất cả các yếu tố được chuyển đổi thành chuỗi để so sánh. Đối với chuỗi, thứ tự từ điển được áp dụng và thực sự "2" > "15".




Để sử dụng thứ tự sắp xếp riêng của chúng ta, chúng ta cần cung cấp một hàm làm đối số của arr.sort().

Hàm nên so sánh hai giá trị tùy ý và trả về:

function compare(a, b) {
  if (a > b) return 1; // if the first value is greater than the second
  if (a == b) return 0; // if values are equal
  if (a < b) return -1; // if the first value is less than the second
}

Ví dụ: để sắp xếp dưới dạng số:

function compareNumeric(a, b) {
  if (a > b) return 1;
  if (a == b) return 0;
  if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];

arr.sort(compareNumeric);

alert(arr);  // 1, 2, 15

Bây giờ nó hoạt động như dự định.

Hãy bước sang một bên và nghĩ những gì đang xảy ra. Có arrthể là mảng của bất cứ điều gì, phải không? Nó có thể chứa số hoặc chuỗi hoặc đối tượng hoặc bất cứ điều gì. Chúng ta có một bộ các mặt hàng . Để sắp xếp nó, chúng ta cần một hàm đặt hàng biết cách so sánh các phần tử của nó. Mặc định là một thứ tự chuỗi.

Các arr.sort(fn)phương pháp thực hiện một thuật toán phân loại chung chung. Chúng ta không cần phải chăm sóc nó như thế nào trong nội bộ công trình (một tối ưu hóa quicksort hầu hết thời gian). Nó sẽ đi theo mảng, so sánh các phần tử của nó bằng cách sử dụng hàm được cung cấp và sắp xếp lại chúng, tất cả những gì chúng ta cần là cung cấp fnphần so sánh.

Nhân tiện, nếu chúng ta muốn biết những yếu tố nào được so sánh – không có gì ngăn cản cảnh báo chúng:

[1, -2, 15, 2, 0, 8].sort(function(a, b) {
  alert( a + " <> " + b );
});

Thuật toán có thể so sánh một yếu tố với nhiều yếu tố khác trong quy trình, nhưng nó cố gắng thực hiện càng ít so sánh càng tốt.

Hàm so sánh có thể trả về bất kỳ số nào

Trên thực tế, một hàm so sánh chỉ được yêu cầu trả về một số dương để nói về mức độ lớn hơn và một số âm để nói là ít hơn.




Điều đó cho phép viết các hàm ngắn hơn:

let arr = [ 1, 2, 15 ];

arr.sort(function(a, b) { return a - b; });

alert(arr);  // 1, 2, 15

Hàm mũi tên

Bạn Nhớ hàm mũi tên? Chúng ta có thể sử dụng chúng ở đây để sắp xếp gọn gàng hơn:

arr.sort( (a, b) => a - b );

Điều này hoạt động chính xác giống như phiên bản dài hơn ở trên.

Sử dụng localeComparecho chuỗi

Ghi nhớ thuật toán so sánh chuỗi ? Nó so sánh các chữ cái theo mã của họ theo mặc định.

Đối với nhiều bảng chữ cái, tốt hơn là sử dụng str.localeComparephương pháp để sắp xếp chính xác các chữ cái, chẳng hạn như Ö.

Ví dụ: hãy sắp xếp một vài quốc gia bằng tiếng Đức:

let countries = ['Österreich', 'Andorra', 'Vietnam'];

alert( countries.sort( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (wrong)

alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (correct!)

đảo ngược

Phương thức Array.reverse đảo ngược thứ tự các phần tử trong arr.

Ví dụ:




let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1

Nó cũng trả về mảng arrsau khi đảo ngược.

split and join

Đây là tình huống từ cuộc sống thực. Chúng ta đang viết một ứng dụng nhắn tin và người này vào danh sách người nhận được phân tách bằng dấu phẩy : John, Pete, Mary. Nhưng đối với chúng ta, một loạt các tên sẽ thoải mái hơn nhiều so với một chuỗi. Làm thế nào để có được nó?

Phương thức str.split(delim) thực hiện chính xác điều đó. Nó phân tách chuỗi thành một mảng bởi dấu phân cách đã cho delim.

Trong ví dụ dưới đây, chúng tôi phân chia bằng dấu phẩy theo sau là khoảng trắng:

let names = 'Bilbo, Gandalf, Nazgul';

let arr = names.split(', ');

for (let name of arr) {
  alert( `A message to ${name}.` ); // A message to Bilbo  (and other names)
}

Các phương thức split có một tùy chọn số đối số thứ hai – một giới hạn về độ dài mảng. Nếu nó được cung cấp, sau đó các yếu tố bổ sung được bỏ qua. Trong thực tế, nó hiếm khi được sử dụng:

let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);

alert(arr); // Bilbo, Gandalf

Chia thành các chữ cái

Gọi hàm split(s)với một khoảng trống sẽ chia chuỗi thành một mảng các chữ cái:

let str = "test";

alert( str.split('') ); // t,e,s,t

Gọi arr.join(glue) để thực hiện ngược lại của phân chia. Nó tạo ra một chuỗi các mục mảng được nối bằng ký tự mà chúng ta truyền vào.

Ví dụ:

let arr = ['Bilbo', 'Gandalf', 'Nazgul'];

let str = arr.join(';'); // glue the array into a string using ;

alert( str ); // Bilbo;Gandalf;Nazgul

reduce/reduceRight

Khi chúng ta cần lặp lại qua một mảng – chúng ta có thể sử dụng forEach, for hoặc for..of.




Khi chúng ta cần lặp lại và trả lại dữ liệu cho từng thành phần – chúng ta có thể sử dụng map.

Các phương thức Array.reduce và Array.reduceRight cũng thuộc về giống đó, nhưng phức tạp hơn một chút. Chúng được sử dụng để tính toán một giá trị duy nhất dựa trên mảng.

Cú pháp:

let value = arr.reduce(function(accumulator, item, index, array) {
  // ...
}, [initial]);

Hàm này được áp dụng cho tất cả các phần tử mảng lần lượt và phần tử mang lại kết quả của nó cho lần gọi tiếp theo.

Sơ lượt:

  • accumulator– là kết quả của lệnh gọi hàm trước, bằng initiallần đầu tiên (nếu initialđược cung cấp).
  • item – là mục mảng hiện tại.
  • index – là vị trí của nó.
  • array – là mảng.

Khi hàm được áp dụng, kết quả của lệnh gọi hàm trước được truyền cho hàm tiếp theo làm đối số đầu tiên.

Vì vậy, đối số đầu tiên về cơ bản là bộ tích lũy lưu trữ kết quả tổng hợp của tất cả các lần thực hiện trước đó. Và cuối cùng, nó trở thành kết quả của reduce.

Nghe có vẻ phức tạp?

Cách dễ nhất để nắm bắt đó là ví dụ.

Ở đây chúng ta nhận được một tổng của một mảng trong một dòng:

let arr = [1, 2, 3, 4, 5];

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15

Hàm được chuyển qua reducechỉ sử dụng 2 đối số là đủ.

Hãy xem chi tiết những gì đang diễn ra.

  1. Trong lần chạy đầu tiên, suminitialgiá trị (đối số cuối cùng reduce), bằng 0currentlà phần tử mảng đầu tiên, bằng 1. Vì vậy, kết quả hàm là 1.
  2. Trong lần chạy thứ hai sum = 1, chúng ta thêm phần tử mảng thứ hai ( 2) vào nó và trả về.
  3. Ở lần chạy thứ 3, sum = 3và chúng ta thêm một yếu tố nữa vào nó, và cứ thế

Luồng tính toán:

Hoặc ở dạng bảng, trong đó mỗi hàng biểu thị một lệnh gọi hàm trên phần tử mảng tiếp theo:

sumcurrentkết quả
cuộc gọi đầu tiên011
cuộc gọi thứ hai123
cuộc gọi thứ ba336
cuộc gọi thứ tư6410
cuộc gọi thứ năm10515

Ở đây chúng ta có thể thấy rõ kết quả của cuộc gọi trước trở thành đối số đầu tiên của cuộc gọi tiếp theo như thế nào.

Chúng ttaôi cũng có thể bỏ qua giá trị ban đầu:

let arr = [1, 2, 3, 4, 5];

// removed initial value from reduce (no 0)
let result = arr.reduce((sum, current) => sum + current);

alert( result ); // 15

Kết quả là như nhau. Đó là bởi vì nếu không có chữ cái đầu tiên, thì reducelấy phần tử đầu tiên của mảng làm giá trị ban đầu và bắt đầu phép lặp từ phần tử thứ 2.

Bảng tính toán giống như trên, trừ hàng đầu tiên.

Nhưng việc sử dụng như vậy đòi hỏi một sự cẩn thận cao độ. Nếu mảng trống, thì reducecuộc gọi không có giá trị ban đầu sẽ báo lỗi.

Đây là một ví dụ:

let arr = [];

// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);

Vì vậy, nên luôn luôn chỉ định giá trị ban đầu.

Phương thức arr.reduceRight thực hiện tương tự, nhưng đi từ phải sang trái.

Array.isArray

Mảng không tạo thành một kiểu ngôn ngữ riêng biệt. Họ dựa trên các đối tượng.

Vì vậy, typeofkhông giúp phân biệt một đối tượng đơn giản với một mảng:

alert(typeof {}); // object
alert(typeof []); // same

Nhiều nhưng mảng được sử dụng thường xuyên đến nỗi có một phương thức đặc biệt cho điều đó: Array.isArray (value) . Nó trả về truenếu valuelà một mảng, và falsenếu không.

alert(Array.isArray({})); // false

alert(Array.isArray([])); // true

Hầu hết các phương thức đều hỗ trợ cho điều này.

Hầu như tất cả các phương pháp mảng chức năng cuộc gọi – như find, filter, map, với một ngoại lệ đáng chú ý của sort, chấp nhận một tham số bổ sung không bắt buộc thisArg.

Tham số đó không được giải thích trong các phần trên, vì nó hiếm khi được sử dụng. Nhưng để hoàn thiện chúng ta phải tìm hiểu nó.

Đây là cú pháp đầy đủ của các phương thức này:

arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg is the optional last argument

Giá trị của tham số thisArg trở thành thischo func.

Ví dụ: ở đây chúng ta sử dụng một phương thức của đối tượng army làm bộ lọc và thisArgchuyển ngữ cảnh:

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let army = {
  minAge: 18,
  maxAge: 27,
  canJoin(user) {
    return user.age >= this.minAge && user.age < this.maxAge;
  }
};

let users = [
  {age: 16},
  {age: 20},
  {age: 23},
  {age: 30}
];

// find users, for who army.canJoin returns true
let soldiers = users.filter(army.canJoin, army);

alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23

Nếu trong ví dụ trên chúng ta đã sử dụng users.filter(army.canJoin), thì army.canJoinnó sẽ được gọi là một hàm độc lập this=undefined, do đó, dẫn đến một lỗi tức thời.

Một cuộc gọi đến users.filter(army.canJoin, army)có thể được thay thế bằng users.filter(user => army.canJoin(user)), điều đó cũng tương tự. Cái trước được sử dụng thường xuyên hơn, vì nó dễ hiểu hơn đối với hầu hết mọi người.

Tóm lược

Một bảng cheat của các phương thức mảng:

  • Để thêm / xóa các thành phần:
    • push(...items) – thêm các mục vào cuối,
    • pop() – trích xuất một mục từ cuối,
    • shift() – trích xuất một mục từ đầu,
    • unshift(...items) – thêm các mục vào đầu.
    • splice(pos, deleteCount, ...items)– tại chỉ mục tại vị trí posxóa deleteCountcác phần tử và chèn items.
    • slice(start, end)– tạo ra một mảng mới, sao chép các phần tử từ vị trí startcho đến khi end(không bao gồm) vào nó.
    • concat(...items)– trả về một mảng mới: sao chép tất cả các thành viên của hiện tại và thêm itemsvào đó. Nếu bất kỳ trong số đó itemslà một mảng, thì các phần tử của nó được lấy.
  • Để tìm kiếm giữa các mục hay phần tử trong mảng:
    • indexOf/lastIndexOf(item, pos)– tìm kiếm itembắt đầu từ vị trí pos, trả về chỉ mục hoặc -1nếu không tìm thấy.
    • includes(value)– trả về truenếu mảng có value, nếu không false.
    • find/filter(func)– lọc các phần tử thông qua hàm, trả về đầu tiên / tất cả các giá trị làm cho nó trả về true.
    • findIndexlà như thế find, nhưng trả về chỉ số thay vì một giá trị.
  • Để lặp lại các mục hay phần tử:
    • forEach(func)– gọi funccho mọi mục, không trả lại bất cứ điều gì.
  • Để chuyển đổi mảng:
    • map(func)– tạo ra một mảng mới từ kết quả gọi funccho mọi phần tử.
    • sort(func) – sắp xếp các mảng tại chỗ, sau đó trả về nó.
    • reverse() – đảo ngược mảng tại chỗ, sau đó trả về nó.
    • split/join – chuyển đổi một chuỗi thành mảng và trả lại.
    • reduce(func, initial)– tính toán một giá trị trên mảng bằng cách gọi funccho từng phần tử và chuyển kết quả trung gian giữa các lệnh gọi.
  • Ngoài ra:
    • Array.isArray(arr)kiểm tra arrlà một mảng.

Xin lưu ý rằng phương pháp sort, reversesplicesửa đổi chính bản thân các mảng đó.

Những phương thức này là những phương thức được sử dụng nhiều nhất, chúng bao gồm 99% trường hợp sử dụng. Nhưng có một vài trường hợp khác:

  • arr.some(fn)/arr.every(fn) kiểm tra mảng. Hàm fnđược gọi trên mỗi phần tử của mảng tương tự map. Nếu bất kỳ / tất cả các kết quả là true, trả lại true, nếu không false.
  • arr.fill(value, start, end) – điền vào mảng với việc lặp lại valuetừ index startđến end.
  • arr.copyWithin(target, start, end) – sao chép các phần tử của nó từ vị trí startcho đến vị trí endvào chính nó , tại vị trí target(ghi đè hiện có).

Để biết danh sách đầy đủ, xem hướng dẫn.

Ngay từ cái nhìn đầu tiên có vẻ như có rất nhiều phương thức, khá khó nhớ. Nhưng thật ra điều đó dễ hơn nhiều.

Nhìn qua bảng cheat chỉ để nhận biết chúng. Sau đó, giải quyết các bài tập của chương này để thực hành, để bạn có kinh nghiệm với các phương thức mảng.

Sau đó, bất cứ khi nào bạn cần làm gì đó với một mảng và bạn không biết làm thế nào – hãy đến đây, nhìn vào bảng cheat và tìm phương thức phù hợp. Ví dụ sẽ giúp bạn viết nó một cách chính xác. Bạn sẽ sớm tự động ghi nhớ các phương thức mà không cần nỗ lực cụ thể từ phía bạn.