Bạn đã bao giờ viết một hàm và nghĩ, "Tôi không biết hàm này sẽ cần bao nhiêu tham số... có thể 2, có thể 20?" Chà, JavaScript đã có sẵn giải pháp với một tính năng gọi là tham số rest.
Chúng giống như một chiếc túi kỳ diệu, thu thập tất cả các tham số dư thừa vào trong một mảng gọn gàng.
Hãy cùng khám phá chúng là gì, cách sử dụng chúng và lý do tại sao chúng lại tuyệt vời.
Điều cơ bản
Tham số rest sử dụng cú pháp ...
để thu thập các tham số dư thừa được truyền vào một hàm và đưa chúng vào một mảng.
function sum(...theArgs) { let total = 0; for (const arg of theArgs) { total += arg; } return total;
} console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4)); // 10
Bạn có thể truyền vào bao nhiêu tham số tùy thích, và hàm sẽ thu thập tất cả chúng.
Quy tắc cú pháp (AKA chữ nhỏ)
- Chỉ được phép có một tham số rest.
- Nó phải là tham số cuối cùng.
- Không được phép có giá trị mặc định hay dấu phẩy thừa sau nó.
Đây là cú pháp hợp lệ:
function logThings(a, b, ...others) { console.log(others);
}
Đây sẽ gây lỗi:
function wrong1(...one, ...two) {} function wrong2(...rest, next) {} function wrong3(...stuff,) {} function wrong4(...stuff = []) {}
Cách hoạt động
Hãy xem một ví dụ đơn giản:
function myFun(a, b, ...manyMoreArgs) { console.log("a", a); console.log("b", b); console.log("manyMoreArgs", manyMoreArgs);
} myFun("one", "two", "three", "four", "five");
Output console:
a one
b two
manyMoreArgs [ 'three', 'four', 'five' ]
Ngay cả khi bạn không truyền giá trị thừa, manyMoreArgs
vẫn là một mảng thực sự:
myFun("one", "two"); // manyMoreArgs -> []
Chỉ truyền vào một tham số thừa?
myFun("one", "two", "three"); // manyMoreArgs -> [ "three" ]
Đếm tham số với Rest
Vì tham số rest là các mảng, bạn có thể dễ dàng sử dụng .length
:
function fun1(...theArgs) { console.log(theArgs.length);
} fun1(); fun1(42); fun1(1, 2, 3);
Kết hợp với các tham số thông thường
Bạn có thể kết hợp các tham số bình thường với tham số rest. Ví dụ:
function multiply(multiplier, ...theArgs) { return theArgs.map((num) => multiplier * num);
} console.log(multiply(2, 10, 20, 30));
Rest vs arguments (Cách cũ)
Bạn có thể sử dụng đối tượng arguments...
nhưng nó hơi lỗi thời.
function oldWay() { const args = Array.from(arguments); console.log(args.sort());
}
Nhưng arguments
không phải là một mảng thực sự, vì vậy đoạn mã sau sẽ không hoạt động:
function nope() { arguments.sort(); }
Với tham số rest, bạn đã làm việc với một mảng thực sự:
function sortArgs(...args) { return args.sort();
} console.log(sortArgs(5, 3, 7, 1));
Destructuring tham số Rest
Bạn có thể phá vỡ các tham số rest, bỏ qua một vài giá trị đầu tiên:
function ignoreFirst(...[, b, c]) { return b + c;
} console.log(ignoreFirst(10, 20, 30)); // 50
Tóm lại
- Sử dụng ...rest khi bạn không biết sẽ nhận được bao nhiêu tham số.
- Đây là một cách thay thế hiện đại, sạch sẽ cho đối tượng arguments.
- Hoạt động tuyệt vời với các phương thức mảng như map, sort, forEach.
- Chỉ có thể có một tham số rest cho mỗi hàm.
- Nó phải là tham số cuối cùng.