Trước ES6: dùng fn.apply(null, arr) — cần null làm thisArg, code "dirty". ES6: fn(...arr) — sạch, rõ ràng.
Cách cũ: apply() + null
<script>
function shareMarket(a, b, c) {
document.write(a + '<br>');
document.write(b + '<br>');
document.write(c + '<br>');
}
const names = ['NSE', 'BSE', 'NIFTY'];
shareMarket.apply(null, names); // Cần null — thisArg không dùng
</script>
Cách mới: Spread Operator (ES6)
<script>
function shareMarket(a, b, c) {
document.write(a + '<br>');
document.write(b + '<br>');
document.write(c + '<br>');
}
const names = ['NSE', 'BSE', 'NIFTY'];
shareMarket(...names); // Sạch, không cần null
</script>
Kết quả (cả hai)
NSE BSE NIFTY
Ưu điểm của Spread
- Không cần
null/thisArggiả. - Có thể kết hợp với arguments khác:
fn('fixed', ...arr, 'last'). - Dễ đọc, dễ debug (stack trace rõ ràng).
- Hiệu suất tốt hơn hoặc ngang
apply().
Rest Parameters (Ngược lại: Nhận mảng)
function sum(...numbers) { // numbers là mảng
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3); // 6
sum(...[1,2,3]); // 6 — spread khi gọi, rest khi định nghĩa
Ví dụ thực tế: Wrapper function
function logAndCall(fn, ...args) {
console.log('Calling', fn.name, 'with', args);
return fn(...args); // Forward với spread
}
function greet(name, age) {
return `Hello ${name}, age ${age}`;
}
logAndCall(greet, 'Alice', 30); // Logs + returns "Hello Alice, age 30"
Lưu ý
- Spread trong function call cũng có stack limit (~100k-200k args) — tránh mảng cực lớn.
- Đối với array-like (arguments, NodeList):
fn(...arrayLike)hoạt động (ES6). - Không dùng cho constructor trực tiếp:
new Date(...[2024, 0, 1])OK, nhưngnew (Class.bind.apply(Class, [null, ...args]))phức tạp — ES6:new Class(...args).