Chức năng sao chép JavaScript

Bởi vì các đối tượng trong JavaScript là các giá trị tham chiếu, bạn không thể chỉ sao chép bằng cách sử dụng

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
6. Nhưng đừng lo, đây là 3 cách để bạn sao chép một đối tượng 👍

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }

Đối tượng là loại tham chiếu

Câu hỏi đầu tiên của bạn có thể là, tại sao tôi không thể sử dụng

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
6. Hãy xem điều gì sẽ xảy ra nếu chúng ta làm điều đó

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);

Cho đến nay, cả hai đối tượng dường như xuất ra cùng một thứ. Vì vậy, không có vấn đề, phải không. Nhưng hãy xem điều gì sẽ xảy ra nếu chúng ta chỉnh sửa đối tượng thứ hai

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱

WTH?. Tôi đã thay đổi

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
8 nhưng tại sao
const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
9 cũng bị ảnh hưởng. Đó là bởi vì Đối tượng là loại tham chiếu. Vì vậy, khi bạn sử dụng
const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
6, nó đã sao chép con trỏ vào không gian bộ nhớ mà nó chiếm giữ. Các loại tham chiếu không giữ giá trị, chúng là một con trỏ tới giá trị trong bộ nhớ

Nếu bạn muốn tìm hiểu thêm về điều này, hãy xem Gordon's Zhu Watch and Codecourse. Miễn phí đăng ký và xem video "So sánh với các đối tượng". Anh ấy đưa ra một lời giải thích siêu tuyệt vời về nó

1. Sử dụng trải rộng

Sử dụng trải rộng sẽ sao chép đối tượng của bạn. Lưu ý đây sẽ là một bản sao nông. Kể từ bài đăng này, toán tử trải rộng cho các đối tượng nhân bản đang ở Giai đoạn 4. Vì vậy, nó chưa chính thức trong thông số kỹ thuật. Vì vậy, nếu bạn sử dụng cái này, bạn sẽ cần biên dịch nó bằng Babel (hoặc thứ gì đó tương tự)

________số 8

2. Sử dụng đối tượng. giao phó

Ngoài ra,

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
1 được phát hành chính thức và cũng sẽ tạo một bản sao nông của đối tượng

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
0

Lưu ý đối số đầu tiên là

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
2 trống, điều này sẽ đảm bảo bạn không thay đổi đối tượng ban đầu 👍

3. Sử dụng JSON

Cách cuối cùng này sẽ cung cấp cho bạn một bản sao sâu. Bây giờ tôi sẽ đề cập, đây là một cách nhanh chóng và bẩn thỉu để nhân bản sâu một đối tượng. Để có một giải pháp mạnh mẽ hơn, tôi khuyên bạn nên sử dụng một cái gì đó như

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
2

Lodash DeepClone so với JSON

Đây là một bình luận từ cộng đồng. Vâng, nó dành cho bài viết trước của tôi, Cách sao chép sâu một mảng. Nhưng ý tưởng vẫn áp dụng cho các đối tượng

Alfredo Salzillo. Tôi muốn bạn lưu ý rằng có một số khác biệt giữa deepClone và JSON. xâu chuỗi/phân tích cú pháp

  • JSON. xâu chuỗi/phân tích cú pháp chỉ hoạt động với Số và Chuỗi và Đối tượng bằng chữ mà không có thuộc tính chức năng hoặc Biểu tượng
  • deepClone hoạt động với tất cả các loại, chức năng và Biểu tượng được sao chép theo tham chiếu

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

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
3

@OlegVaraksin. Phương thức JSON gặp sự cố với các phụ thuộc vòng tròn. Hơn nữa, thứ tự các thuộc tính trong đối tượng nhân bản có thể khác

Bản sao nông vs Bản sao sâu

Khi tôi sử dụng trải rộng

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
3 để sao chép một đối tượng, tôi chỉ tạo một bản sao nông. Nếu mảng được lồng vào nhau hoặc nhiều chiều, nó sẽ không hoạt động. Đây là ví dụ của chúng tôi, chúng tôi sẽ sử dụng

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
5

Bản sao nông

Hãy sao chép đối tượng của chúng ta bằng cách sử dụng trải rộng

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
6

Vì vậy, chúng tôi đã thay đổi đối tượng nhân bản của mình bằng cách thay đổi thành phố. Hãy xem đầu ra

const food = { beef: '🥩', bacon: '🥓' }


// "Spread"
{ ...food }


// "Object.assign"
Object.assign({}, food)


// "JSON"
JSON.parse(JSON.stringify(food))

// RESULT:
// { beef: '🥩', bacon: '🥓' }
7

Một bản sao nông có nghĩa là cấp độ đầu tiên được sao chép, các cấp độ sâu hơn được tham chiếu

Sao chép sâu

Hãy lấy ví dụ tương tự nhưng áp dụng một bản sao sâu bằng cách sử dụng "JSON"

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
0

Như bạn có thể thấy, bản sao sâu là bản sao thực sự cho các đối tượng lồng nhau. Thường thì bản sao nông là đủ tốt, bạn không thực sự cần bản sao sâu. Nó giống như súng bắn đinh vs búa. Hầu hết thời gian búa là hoàn toàn tốt. Sử dụng súng bắn đinh cho một số tác phẩm nghệ thuật và thủ công nhỏ thường là quá mức cần thiết, một chiếc búa cũng được. Đó là tất cả về việc sử dụng đúng công cụ cho đúng công việc 🤓

Hiệu suất

Rất tiếc là mình không viết test được cho spread vì nó chưa có trong spec chính thức. Tuy nhiên, tôi đã đưa nó vào thử nghiệm để bạn có thể chạy nó trong tương lai 😝. Nhưng kết quả cho thấy

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
1 nhanh hơn rất nhiều so với
const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
5

Kiểm tra hiệu suất

Đầu vào của cộng đồng

Vật. chỉ định vs lây lan

@d9el. Điều quan trọng cần lưu ý là Đối tượng. gán là một hàm sửa đổi và trả về đối tượng đích. Trong ví dụ của Samantha sử dụng như sau,

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
1

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
2 là đối tượng được sửa đổi. Đối tượng đích không được tham chiếu bởi bất kỳ biến nào tại thời điểm đó, nhưng vì
const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
1 trả về đối tượng đích nên chúng ta có thể lưu đối tượng được gán kết quả vào biến
const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
8. Chúng tôi có thể chuyển ví dụ của mình lên và sử dụng như sau

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
2

Rõ ràng, giá trị của

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
9 trong đối tượng thực phẩm của chúng tôi là sai, vì vậy chúng tôi có thể gán giá trị đúng của
const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
9 bằng cách sử dụng
const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
1. Chúng tôi thực sự không sử dụng giá trị được trả về của hàm, nhưng chúng tôi đang sửa đổi đối tượng đích mà chúng tôi đã tham chiếu với const
const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
2

Mặt khác, trải rộng là một toán tử sao chép các thuộc tính của một đối tượng vào một đối tượng mới. Nếu chúng tôi muốn sao chép ví dụ trên bằng cách sử dụng trải rộng để sửa đổi biến

const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
3 của chúng tôi

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
3

const obj2.three = 3;

console.log(obj2);
// {one: 1, two: 2, three: 3}; <-- ✅

console.log(obj);
// {one: 1, two: 2, three: 3}; <-- 😱
3 chúng tôi gặp lỗi vì chúng tôi sử dụng trải rộng khi tạo đối tượng mới và do đó đang gán một đối tượng hoàn toàn mới cho
const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
2 đã được khai báo với
const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
6, điều này là bất hợp pháp. Vì vậy, chúng ta có thể chọn khai báo một biến mới để giữ đối tượng mới của mình, như sau

const obj = { one: 1, two: 2 };

const obj2 = obj;

console.log(
  obj, // {one: 1, two: 2};
  obj2, // {one: 1, two: 2};
);
4

hoặc chúng ta có thể khai báo

const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
2 với
const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
8 hoặc
const food = { beef: '🥩', bacon: '🥓' };

const cloneFood = { ...food };

console.log(cloneFood);
// { beef: '🥩', bacon: '🥓' }
9, điều này sẽ cho phép chúng ta gán một đối tượng hoàn toàn mới

Làm cách nào để sao chép chức năng trong JavaScript?

Để sao chép một đối tượng trong JavaScript, bạn có ba tùy chọn. .
Sử dụng mức chênh lệch (. ) cú pháp
Sử dụng đối tượng. phương thức gán()
Sử dụng JSON. stringify() và JSON. phương pháp phân tích ()

Làm cách nào để lấy giá trị đã sao chép trong JavaScript?

3 cách sao chép theo giá trị bất kỳ loại dữ liệu tổng hợp nào trong JavaScript .
Sử dụng mức chênh lệch (. ) cú pháp
Sử dụng đối tượng. phương thức gán()
Sử dụng JSON. stringify() và JSON. phương pháp phân tích ()

Làm cách nào để sao chép văn bản đã chọn trong JavaScript?

Sử dụng HTMLInputElement. select() để chọn nội dung của phần tử Sử dụng tài liệu. execCommand('copy') để sao chép nội dung của .

Làm cách nào để sao chép văn bản từ div trong JavaScript?

Các bước sao chép văn bản trong javascript1. Tạo một phần tử textarea2. Lấy văn bản từ div bằng cách sử dụng div. bên trong3. .