03:05:08 6/3/2025 - 0 views -
Tôi sẽ giải thích một cách toàn diện về toán tử spread (...
) trong JavaScript, đặc biệt liên quan đến việc sao chép (copy) và các ứng dụng khác của nó. Tôi sẽ trình bày chi tiết bằng tiếng Việt, kèm ví dụ và lưu ý quan trọng.
Toán tử spread (...
) được giới thiệu trong ES6 (ES2015), cho phép "lan tỏa" (spread) các phần tử của một iterable (như mảng, chuỗi) hoặc các thuộc tính của một object thành các phần tử riêng lẻ. Nó thường được dùng để:
Toán tử spread thường được dùng để tạo shallow copy (bản sao nông) của mảng hoặc object.
const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // Sao chép arr1 sang arr2
arr2.push(4); // Thay đổi arr2 không ảnh hưởng arr1
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [1, 2, 3, 4]
const arr1 = [1, { a: 2 }];
const arr2 = [...arr1];
arr2[1].a = 3; // Thay đổi object trong arr2 cũng ảnh hưởng arr1
console.log(arr1); // [1, { a: 3 }]
console.log(arr2); // [1, { a: 3 }]
const obj1 = { name: "Nguyễn Văn A", age: 25 };
const obj2 = { ...obj1 }; // Sao chép obj1 sang obj2
obj2.age = 26; // Thay đổi obj2 không ảnh hưởng obj1
console.log(obj1); // { name: "Nguyễn Văn A", age: 25 }
console.log(obj2); // { name: "Nguyễn Văn A", age: 26 }
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 };
obj2.b.c = 3; // Thay đổi b.c trong obj2 cũng ảnh hưởng obj1
console.log(obj1); // { a: 1, b: { c: 3 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
Ngoài sao chép, toán tử spread còn có nhiều ứng dụng hữu ích:
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4]
const obj1 = { name: "Nguyễn Văn A" };
const obj2 = { age: 25 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { name: "Nguyễn Văn A", age: 25 }
const obj1 = { key: 1 };
const obj2 = { key: 2 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { key: 2 }
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
const str = "Hello";
const chars = [...str];
console.log(chars); // ["H", "e", "l", "l", "o"]
const arr = [1, 2];
const newArr = [...arr, 3];
console.log(arr); // [1, 2]
console.log(newArr); // [1, 2, 3]
slice()
(dành cho mảng)slice()
chỉ dùng cho mảng:const arr1 = [1, 2, 3];
const arr2 = arr1.slice();
Object.assign()
(dành cho object)Object.assign()
:const obj1 = { a: 1 };
const obj2 = Object.assign({}, obj1);
JSON.parse(JSON.stringify())
:const obj1 = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj1));
deepCopy.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
function Person() { this.name = "A"; }
Person.prototype.age = 25;
const p1 = new Person();
const p2 = { ...p1 };
console.log(p2.age); // undefined (không sao chép age từ prototype)
const num = 123;
console.log([...num]); // TypeError: num is not iterable
Object.assign()
.const state = { count: 1 };
const newState = { ...state, count: state.count + 1 };
const defaults = { timeout: 5000 };
const options = { ...defaults, url: "https://api.com" };
Nếu bạn muốn tôi giải thích thêm về bất kỳ phần nào (ví dụ: shallow copy vs deep copy, cách tối ưu hiệu suất, hoặc ứng dụng cụ thể), hãy cho tôi biết nhé! Bạn cũng có thể yêu cầu ví dụ thực tế hoặc bài tập để thực hành.