Làm việc với Javascript nhiều rồi nhưng bạn đã bao giờ gặp trường hợp mà khi cần sao chép một đối tượng chưa? . Sau này, tùy chọn từng chức năng mà cần sao chép cấu hình mặc định và chỉnh sửa nó. Lúc sau quay lại, đối tượng cấu hình mặc định cũng được chỉnh sửa theo. Kỳ lạ. ?
Nội dung chính của bài viết
- Đặt vấn đề khi sao chép một đối tượng trong Javascript
- Các đối tượng nhân bản sâu
- 1. Sử dụng toán tử Spread
- 2. Use Object. giao phó
- 3. Biện pháp rất mạnh là sử dụng JSON
- 4. Tự viết hàm sao chép đối tượng
- pause
Đặt vấn đề khi sao chép một đối tượng trong Javascript
Để bạn dễ hình dung, mình ví dụ bằng đoạn mã khi bạn thực hiện sao chép một đối tượng
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = defaultConfig; customConfig["debug"] = false; customConfig["name"] = "Cấu hình cho KH"; console.log[defaultConfig];
Kết quả
Như vậy, mặc dù bạn không hề chỉnh sửa defaultConfig
nhưng nó cũng bị biến đổi theo sau khi cập nhật customConfig
Nguyên nhân của vấn đề trên nó liên quan tới kiểu dữ liệu tham chiếu và tham số. With Object it is reference data type. Thức là các biến chỉ lưu trữ địa chỉ vùng nhớ của đối tượng mà thôi. Nên khi gán biến đó cho một biến khác thì bản chất là tạo ra hai biến cùng con trỏ tới một vùng nhớ
Do đó, deep clone a object là phương pháp tạo vùng nhớ mới độc lập với vùng nhớ ban đầu
Các đối tượng nhân bản sâu
Ok, sau khi hiểu vấn đề và bản chất rồi, chúng ta cùng nhau thử một số cách để sao chép sâu một đối tượng trong javascript
1. Sử dụng toán tử Spread
Spread là toán tử thực hiện “làm phẳng” một đối tượng. Làm vậy, sau khi “làm phẳng” bạn cần tạo mới một đối tượng thông qua cú pháp {}
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = {...defaultConfig}; customConfig["debug"] = false; customConfig["name"] = "Cấu hình cho KH"; console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi"}
Nhược điểm của phương pháp này là chỉ có tác dụng với đối tượng không lồng nhau. Đối tượng mà lồng nhau nhiều cấp thì cũng “hết phép”.
Ví dụ.
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", data: { position: 1 } } const customConfig = {...defaultConfig}; customConfig["debug"] = false; customConfig["name"] = "Cấu hình cho KH"; customConfig["data"]["position"] = 2 console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi", data: { postion: 2}}
Như vậy là không được rồi. Phải dùng biện pháp mạnh hơn [tham khảo phương pháp số 2 mà mình giới thiệu về phía cuối bài viết nhé]
2. Use Object. giao phó
Giải pháp này cũng tương tự với việc sử dụng toán tự Spread
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = Object.assign[{}, defaultConfig]; console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi"}
Điểm khác biệt duy nhất so với việc sử dụng toán tử Spread là hàm Object.assign[]
có khả năng hỗ trợ nhiều trình duyệt hơn
3. Biện pháp rất mạnh là sử dụng JSON
Nếu như hai giải pháp về việc không trả lời được yêu cầu deep clone của bạn thì đây là lời khen thuốc cực mạnh, sẽ giải quyết vấn đề của bạn
That main is used
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = {...defaultConfig}; customConfig["debug"] = false; customConfig["name"] = "Cấu hình cho KH"; console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi"}0 results with
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = {...defaultConfig}; customConfig["debug"] = false; customConfig["name"] = "Cấu hình cho KH"; console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi"}0
const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", } const customConfig = JSON.parse[JSON.stringify[defaultConfig]];
Giải pháp này nhìn thì hơi buồn cười nhưng nó thực sự có võ đấy
4. Tự viết hàm sao chép đối tượng
Nếu trường hợp bạn muốn tự làm chủ công nghệ deep clone Object, chúng ta có thể tự viết hàm tạo đối tượng. Bằng cách đệ quy để duyệt qua từng thuộc tính của đối tượng gốc và tạo đối tượng mới
function cloneObject[obj] { var clone = {}; for[var i in obj] { if[obj[i] != null && typeof[obj[i]]=="object"] clone[i] = cloneObject[obj[i]]; else clone[i] = obj[i]; } return clone; } // Cách sử dụng const defaultConfig = { debug: true, name: "Cấu hình mặc định", connectType: "Wifi", data: { position: 1 } } const customConfig = cloneObject[defaultConfig] customConfig["debug"] = false; customConfig["data"]["position"] = 2; console.log[defaultConfig]; // {debug: true, name: "Cấu hình mặc định", connectType: "Wifi", data: {position: 1}}
pause
Trên đây là một số cách để bạn có thể sao chép sâu các đối tượng trong Javascript. Mình hi vọng sẽ có ích cho dự án của bạn
Nếu bài viết có ích thì đừng ngại để lại một bình luận động viên mình nhé. Hẹn gặp lại ở bài viết sau nhé
💥 Đọc thêm về Javascript
- [Đoạn mã] Xác thực email hợp lệ bằng Javascript
- [Javascript] Các cách xóa phần tử trong mảng [Array]
- Ý niệm nâng Javascript là gì?
Miễn phí khóa học React Native
Bạn có muốn tải xuống toàn bộ video của khóa học rất nổi tiếng về React Native này không?
- THẺ
- jav
- javascript cơ bản
liên kết
Bài trước Lỗi chạy quảng cáo Facebook thường gặp và cách giải quyết
Bài tiếp theo Biến động để tự học thiết lập hiệu quả hiệu quả
sơn dương
Tên đầy đủ là Dương Anh Sơn. Tốt nghiệp ĐH Bách Khoa Hà Nội. Mình bắt đầu nghiệp coder khi mà ra trường đúng là xin được làm đúng chuyên ngành. Mình tin rằng chỉ có chia sẻ kiến thức mới là cách học tập nhanh nhất. Các bạn góp ý bài viết của mình bằng cách comment bên dưới nhé