2015-03-05 18 views
11

Tôi đang cố gắng sao chép sâu mảng các đối tượng lồng nhau trong javascript. Mảng của tôi trông giống như thế nàyMảng sao chép sâu của các đối tượng lồng nhau trong javascript

var arr = [{name:"adam",age:"21"}, 
    {name:"freddie",age:"35",children:[{name:"mercury",age:"25"}]}, 
    {name:"jim",age:"35",children:[{name:"morrison",age:"25",children:[{name:"some", age:"40"}]}]} 
    ]; 

Tôi muốn tạo bản sao sâu của mọi đối tượng bên trong mảng mà tôi muốn tạo bản sao chính xác của mảng vào mảng mới mà không có tham chiếu đối tượng. Độ sâu của mảng cũng không rõ là mảng con có thể tối đa bất kỳ mức nào. Tôi đã đi qua liên kết này Copying of an array of objects to another Array without object reference in javascript(Deep copy) nhưng điều đó không giúp tôi. Tôi googled và tìm thấy một số giải pháp trong jQuery nhưng điều đó đã không giúp tôi như tôi không có kiến ​​thức về jQuery.

Tôi cũng đã cố gắng thực hiện nó với đệ quy nhưng điều đó không làm việc quá http://ideone.com/kJi5X3

Tôi muốn làm điều đó trong javascript chỉ mà không sử dụng jQuery hoặc bất cứ điều gì. Tôi mới vào JavaScript vì vậy tôi có thể đã bỏ lỡ nếu có bất kỳ thư viện hoặc phương pháp đơn giản để làm điều này. Hãy giúp tôi giải quyết vấn đề này. Cảm ơn trước.

+1

Bạn đã liên kết với câu hỏi rằng điều này có thể đã bị đóng và trùng lặp và cho biết điều đó không hữu ích - bạn có thể làm rõ _why_ nó không hữu ích, vì vậy chúng tôi hiểu tại sao điều này không trùng lặp với câu hỏi đó? –

+0

Cũng lưu ý rằng jQuery là _just một thư viện javascript_, nếu có một giải pháp jQuery, bạn có quyết định ra rằng thư viện trong khi một số khác sẽ được chấp nhận? –

+0

@ James Thorpe - Không có tôi đang tự hỏi nếu có bất kỳ cách nào để làm điều đó với đệ quy hoặc bất kỳ logic khác tôi không có kiến ​​thức về jQuery và tôi muốn làm điều này càng sớm càng tốt. – user2912611

Trả lời

24

Bạn có hai lựa chọn chính:

  1. Sử dụng JSON.stringifyJSON.parse:

    var copy = JSON.parse(JSON.stringify(original)); 
    

    Nhưng Tôi chưa bao giờ thích điều đó. Một chuyến đi khứ hồi qua văn bản không hiệu quả ở mức tốt nhất và nó sẽ không xử lý các giá trị Date, RegExp, undefined, v.v., trừ khi bạn viết bộ đệm thay thế và bộ thu hồi.

  2. Sử dụng một hàm đệ quy, một cái gì đó như thế này:

var toString = Object.prototype.toString; 
 
function deepCopy(obj) { 
 
    var rv; 
 

 
    switch (typeof obj) { 
 
     case "object": 
 
      if (obj === null) { 
 
       // null => null 
 
       rv = null; 
 
      } else { 
 
       switch (toString.call(obj)) { 
 
        case "[object Array]": 
 
         // It's an array, create a new array with 
 
         // deep copies of the entries 
 
         rv = obj.map(deepCopy); 
 
         break; 
 
        case "[object Date]": 
 
         // Clone the date 
 
         rv = new Date(obj); 
 
         break; 
 
        case "[object RegExp]": 
 
         // Clone the RegExp 
 
         rv = new RegExp(obj); 
 
         break; 
 
        // ...probably a few others 
 
        default: 
 
         // Some other kind of object, deep-copy its 
 
         // properties into a new object 
 
         rv = Object.keys(obj).reduce(function(prev, key) { 
 
          prev[key] = deepCopy(obj[key]); 
 
          return prev; 
 
         }, {}); 
 
         break; 
 
       } 
 
      } 
 
      break; 
 
     default: 
 
      // It's a primitive, copy via assignment 
 
      rv = obj; 
 
      break; 
 
    } 
 
    return rv; 
 
} 
 
var a = [1, {foo: "bar"}, ['a', 'b'], new Date()]; 
 
snippet.log(JSON.stringify(a)); 
 
var b = deepCopy(a); 
 
snippet.log(JSON.stringify(b));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Lưu ý rằng sử dụng trên ES5 tính năng có mặt trên tất cả các trình duyệt hiện đại nhưng không phải một số những người lớn tuổi, như IE8 . Tuy nhiên, tất cả các tính năng được sử dụng ở trên có thể được thực hiện cho các trình duyệt cũ hơn.

Điều đó không cố gắng xử lý các hàm xây dựng tùy chỉnh hoặc bảo toàn các mẫu thử trên các đối tượng trong mảng; làm như vậy làm cho mọi thứ đáng kể hơn phức tạp hơn và không thể hoàn hảo nếu không có quy ước về cách gọi những nhà xây dựng đó cho một thao tác sao chép. Bạn có thể đạt được gần bằng cách gán cùng một nguyên mẫu, nhưng điều đó sẽ không tính đến logic trong hàm hàm dựng và đặc biệt cho các hàm được thiết lập như các bao đóng bên trong nó.

+0

Đám đông làm việc hoàn hảo, Cảm ơn bạn rất nhiều :) – user2912611

Các vấn đề liên quan