Tôi không có tài năng gì cả. Tôi chỉ đam mê hiểu biết
Spread Operator Và Rest Parameters Trong Javascript

Spread Operator Và Rest Parameters Trong Javascript


Ngày 19 Tháng 5 Năm 2020

Hôm nay bạn hãy cùng mình đi vào tìm hiểu về khái niệm cũng như cách sử dụng Spread Operator và Rest Parameters trong ngôn ngữ lập trình Javascript để phát triển web nhé.

Trong phiên bản es6 có cung cấp cho hai tiện ích là spread operator và rest parameters để chúng ta có thể dễ dàng làm việc với tham số trong hàm, mảng, object... Bây giờ để hiểu rõ hơn chúng ta cùng nhau đi vào tìm hiểu nhé.

Rest Parameters(...)

Để hiểu công dụng của nó thì mình sẽ đi vào thử viết hàm tính tổng của các tham số để xem hàm sẽ xử lý thế nào nhé:

Đoạn Code:

 function tinhTong(a, b) {
   return a + b;
}
console.log(tinhTong(1,2,3,4,5,6));

Kết Quả:

Tính tổng nhiều tham số

Mình có lưu ý là với một hàm bạn có thể truyền bao nhiêu tham số tùy ý mà không cần quan tâm đến cách khai báo hàm nha. Ở ví dụ trên thì hàm tinhTong chỉ lấy hai tham số đầu để xử lý là 1 và 2 nên chúng ta có kết quả ngoài màn hình là 3.
Vậy làm thế nào để nó có thể tính tổng tất cả tham số chúng ta truyền vào?

Đó chính là lý do mình muốn giới thiệu về tiện ích Rest Parameters trong javascript. Nó cho phép chúng ta biểu thị các tham số còn lại thành kiểu dữ liệu mảng và được đi theo với dấu .... Để nắm rõ hơn bạn xem cú pháp của nó nhé:

 function Tên Hàm (...Tham Số) {
  /*Đoạn mã thực thi*/
}

...Tham Số Còn Lại chính là rest parameters. Nó lưu giữ tất cả tham số được truyền vào dưới kiễu dữ liệu mảng giúp chúng ta có thể lấy phần tử và tính toán linh hoạt hơn. Bây giờ chúng ta dùng rest parameters để thử giải quyết vấn đề trên xem sao nhé:

Đoạn Code:

 function tinhTong(...mang) {
let ketQua = 0;
 for( let phanTu of mang) {
   ketQua += phanTu;
 }
 return ketQua;
 }
console.log(tinhTong(1,2,3,4,5,6));
console.log(tinhTong(1,2,3,4));
console.log(tinhTong(1,2,3));

Kết Quả:

Tính tổng bằng rest parameters

Ở ví dụ trên chúng ta sẽ sử dụng biến ketQua để lưu trữ giá trị tổng khi cộng với các phần tử trong mảng bằng vòng lặp for...of . Bây giờ bạn truyền bao nhiêu tham số thì hàm tinhTong đều có thể trả về kết quả giá trị tổng của các tham số đó. Thật tiện lợi phải không nào!

Sử dụng rest parameters với arrow function:

Chúng ta có thể kết hợp với rest parameters với arrow function để giải quyết vấn đề trên một cách nhanh chóng bằng phương thức reduce(). Để hiểu rõ hơn bạn xem đoạn code sau nhé:

Đoạn Code:

 function tinhTong(...mang) {
  return mang.reduce((tong, phanTu) => tong + phanTu, 0);
}
console.log(tinhTong(1,2,3,4,5,6));
console.log(tinhTong(1,2,3,4));
console.log(tinhTong(1,2,3));

Kết Quả:

rest parameters và arrow function

Nếu như bạn muốn tìm hiểu thêm hay tham khảo về phương thức reduce() thì nhấn vào đây nhé!

Sử dụng rest parameters với các tham số khác:

Nãy giờ chúng ta chỉ sử dụng nó là tham số chính và duy nhất trong hàm. Phần nay ta sẽ đi vào kết hợp rest parameters với các tham số khác được truyền vào trong hàm thông qua ví dụ dưới đây nhé:

Đoạn Code:

 function xinChao(chu1, chu2, ...mang) {
  console.log(chu1 + " " + chu2);
  console.log(mang[0]);
   console.log(mang[1]);
}
xinChao("Xin", "Chào", "Các", "Bạn");

Kết Quả:

rest parameters với nhiều tham số

Ở ví dụ trên khi chúng ta khai báo như hàm xinChao thì hai tham số đầu tiên sẽ được gán vào biến là chu1chu2. Còn các tham số còn lại sẽ được chứa trong biến mang. Và khi muốn sử dụng các tham số đó thì chúng ta lấy phần tử như bình thường khi làm việc với kiểu dữ liệu mảng.

Mình có lưu ý quan trọng là rest parameters phải được đặt ở vị trí cuối cùng khi khai báo tham số trong hàm nha. Nếu không nó sẽ gây ra lỗi như hình ảnh bên dưới:

Lỗi khi dùng rest parameters

Sử dụng biến arguments:

Trước khi tiện ích rest parameters được giới thiệu và sử dụng rộng rãi như ngày nay thì chúng ta chỉ có một cách để lấy tất cả tham số cho hàm bằng cách sử dụng arguments. Giá trị trả về của nó là một đối tượng giống như mảng nhưng chúng ta không thể sử dụng phương thức mảng với giá trị này như Mảng.map, Mảng.filter... Bây giờ chúng ta thử lấy các phần tử bằng biến arguments thông qua ví dụ sau nhé:

Đoạn Code:

 function xinChao() {
  console.log(arguments.length);
  console.log(arguments[0]);
   console.log(arguments[1]);
}
xinChao("Xin", "Chào", "Các", "Bạn");

Kết Quả:

Sử dụng biến arguments

Spread Operator(...)

Spread Operator cũng là một tiện ích được cung cấp trong phiên bản ES6 được sử dụng với dấu ... cho phép chúng ta mở rộng một đối tượng nào đó. Và nó thường được sử dụng với kiểu dữ liệu là Mảng, Map và Set.
Bây giờ để dễ hình dung chúng ta sẽ đi ví dụ nối mảng bằng hai cách để bạn có thể thấy được sự hữu ích của nó nhé.

Nối mảng bằng phương thức concat():

Đoạn Code:

 let mang1 = [1, 2, 3];
let mang2 = [4, 5, 6];
let ketQua = mang1.concat(mang2);

console.log(ketQua);

Kết Quả:

Nối mảng bằng concat
Nối mảng bằng sử dụng toán tử spread:

Đoạn Code:

 let mang1 = [4, 5, 6];
let ketQua = [1, 2, 3, ...mang1];

console.log(ketQua);

Kết Quả:

Nối mảng bằng spread

Như bạn thấy khi chúng ta sử dụng toán tử spread giúp đoạn mã dễ nhìn hơn, tiết kiệm được thời gian và công sức hơn.

Không giống như rest parameters, vị trí của nó phải là tham số cuối cùng trong khai báo hàm. Thì với toán tử spread thì bạn có thể đặt ở bất cứ đâu tùy vào mục đích của chúng ta. Để nắm rõ hơn bạn xem đoạn code sau nhé:

Đoạn Code:

 let mang1 = [4, 5, 6];
let ketQua = [...mang1, 1, 2, 3];

console.log(ketQua);

Kết Quả:

Vị trí của spread trong mảng

Sử dụng nhiều toán tử spread:

Do tính linh hoạt của nó nên chúng ta có thể kết hợp nhiều toán tử spread lại với nhau. Bây giờ để hiểu rõ hơn bạn xem đoạn code sau nhé:

Đoạn Code:

 let mang1 = [4, 5, 6];
let mang2 = [10, 11, 12];
let ketQua = [1, 2, 3, ...mang1, 7, 8, 9, ...mang2];

console.log(ketQua);

Kết Quả:

Kết hộp nhiều toán tử spread trong mảng

Sao chép mảng bằng toán tử spread:

Chúng ta có thể sao chép mảng bằng toán tử spread. Và khi mảng sao chép thay đối thì nó cũng không ảnh hưởng đến mảng chính nha. Bây giờ chúng ta sẽ đi vào ví dụ chi tiết sau đây nhé:

Đoạn Code:

 let mang1 = [4, 5, 6];
let mang2 = [...mang1];
mang2[0] = 10;

console.log(mang1);
console.log(mang2);

Kết Quả:

Sao chép mảng bằng toán tử spread

Sử dụng toán tử spread và chuỗi:

Thông thường khi bạn muốn tách một chuỗi thành mảng thì chúng ta thường dùng phương thức là split(). Toán tử spread cũng giúp chúng ta thực hiện điều tương tự phía trên. Để hiểu rõ hơn bạn xem đoạn code sau nhé:

Đoạn Code:

 let mang = ['A', ...'BC', 'D'];
console.log(mang);

Kết Quả:

Toán tử spread với chuỗi

Sử dụng toán tử spread và Math:

Bây giờ chúng ta sẽ thử đi vào ví dụ tìm hiểu cách lấy số nhỏ nhất bằng phương thức Math.min() nhé:

Đoạn Code:

 let soNhoNhat = Math.min(10, 50, 40, 5);
console.log(soNhoNhat);

Kết Quả:

Sử dụng Math.min()

Ta cũng có thể truyền một mảng như tham số vào trong phương thức Math.min() bằng cách sử dụng toán tử spread. Để hiểu rõ hơn bạn xem đoạn code sau nhé:

Đoạn Code:

 let mang = [10, 50, 40, 5];
let soNhoNhat = Math.min(...mang);
console.log(soNhoNhat);

Kết Quả:

Sử dụng Math.min() với spread

Tổng kết:

Qua đây mình mong bài viết sẽ giúp bạn hiểu được Spread Operator Và Rest Parameters trong ngôn ngữ Javascript và nếu có thắc mắc gì cứ gửi email mình sẽ phản hồi sớm nhất có thể. Rất mong bạn tiếp tục ủng hộ trang web để mình có thể viết nhiều bài hay hơn nữa nhé. Chúc bạn có một ngày vui vẻ!