Hướng dẫn copy array javascript without reference - sao chép javascript mảng mà không có tham chiếu

Trong JavaScript, các kỹ thuật bản sao sâu phụ thuộc vào các yếu tố trong một mảng. Hãy bắt đầu ở đó.

Ba loại yếu tố

Các yếu tố có thể là: giá trị theo nghĩa đen, cấu trúc theo nghĩa đen hoặc nguyên mẫu.

// Literal values [type1]
const booleanLiteral = true;
const numberLiteral = 1;
const stringLiteral = 'true';

// Literal structures [type2]
const arrayLiteral = [];
const objectLiteral = {};

// Prototypes [type3]
const booleanPrototype = new Bool[true];
const numberPrototype = new Number[1];
const stringPrototype = new String['true'];
const arrayPrototype = new Array[];
const objectPrototype = new Object[]; // or `new function [] {}

Từ các yếu tố này, chúng ta có thể tạo ba loại mảng.

// 1] Array of literal-values [boolean, number, string] 
const type1 = [ true, 1, "true" ];

// 2] Array of literal-structures [array, object]
const type2 = [ [], {} ];

// 3] Array of prototype-objects [function]
const type3 = [ function [] {}, function [] {} ];

Kỹ thuật sao chép sâu phụ thuộc vào ba loại mảng

Dựa trên các loại yếu tố trong mảng, chúng ta có thể sử dụng các kỹ thuật khác nhau để sao chép sâu.

Kỹ thuật sao chép sâu

Điểm chuẩn

//www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison

  • Mảng các giá trị theo nghĩa đen [Type1] [ ...myArray ], myArray.splice[0], myArray.slice[]myArray.concat[] có thể được sử dụng để sao chép các mảng sâu với các giá trị theo nghĩa đen [boolean, số và chuỗi]; Trong đó slice[] có hiệu suất cao nhất trong Chrome và lan truyền

    // 1] Array of literal-values [boolean, number, string] 
    const type1 = [ true, 1, "true" ];
    
    // 2] Array of literal-structures [array, object]
    const type2 = [ [], {} ];
    
    // 3] Array of prototype-objects [function]
    const type3 = [ function [] {}, function [] {} ];
    
    0 có hiệu suất cao nhất trong Firefox.
    The [ ...myArray ], myArray.splice[0], myArray.slice[], and myArray.concat[] techniques can be used to deep copy arrays with literal values [boolean, number, and string] only; where slice[] has the highest performance in Chrome, and spread
    // 1] Array of literal-values [boolean, number, string] 
    const type1 = [ true, 1, "true" ];
    
    // 2] Array of literal-structures [array, object]
    const type2 = [ [], {} ];
    
    // 3] Array of prototype-objects [function]
    const type3 = [ function [] {}, function [] {} ];
    
    0 has the highest performance in Firefox.

  • Mảng của các giá trị theo nghĩa đen [Type1] và cấu trúc theo nghĩa đen [Type2] Kỹ thuật

    // 1] Array of literal-values [boolean, number, string] 
    const type1 = [ true, 1, "true" ];
    
    // 2] Array of literal-structures [array, object]
    const type2 = [ [], {} ];
    
    // 3] Array of prototype-objects [function]
    const type3 = [ function [] {}, function [] {} ];
    
    1 có thể được sử dụng để sao chép sâu các giá trị theo nghĩa đen [boolean, số, chuỗi] và cấu trúc theo nghĩa đen [mảng, đối tượng], nhưng không phải là đối tượng nguyên mẫu.
    The
    // 1] Array of literal-values [boolean, number, string] 
    const type1 = [ true, 1, "true" ];
    
    // 2] Array of literal-structures [array, object]
    const type2 = [ [], {} ];
    
    // 3] Array of prototype-objects [function]
    const type3 = [ function [] {}, function [] {} ];
    
    1 technique can be used to deep copy literal values [boolean, number, string] and literal structures [array, object], but not prototype objects.

  • Tất cả các mảng [Type1, type2, type3]

    • Các kỹ thuật Lo-Dash
      // 1] Array of literal-values [boolean, number, string] 
      const type1 = [ true, 1, "true" ];
      
      // 2] Array of literal-structures [array, object]
      const type2 = [ [], {} ];
      
      // 3] Array of prototype-objects [function]
      const type3 = [ function [] {}, function [] {} ];
      
      2 hoặc jQuery
      // 1] Array of literal-values [boolean, number, string] 
      const type1 = [ true, 1, "true" ];
      
      // 2] Array of literal-structures [array, object]
      const type2 = [ [], {} ];
      
      // 3] Array of prototype-objects [function]
      const type3 = [ function [] {}, function [] {} ];
      
      3 có thể được sử dụng để kết hợp sâu tất cả các loại mảng. Trong đó kỹ thuật Lodash
      // 1] Array of literal-values [boolean, number, string] 
      const type1 = [ true, 1, "true" ];
      
      // 2] Array of literal-structures [array, object]
      const type2 = [ [], {} ];
      
      // 3] Array of prototype-objects [function]
      const type3 = [ function [] {}, function [] {} ];
      
      4 có hiệu suất cao nhất.
    • Và đối với những người tránh các thư viện của bên thứ ba, chức năng tùy chỉnh bên dưới sẽ kết hợp sâu tất cả các loại mảng, với hiệu suất thấp hơn
      // 1] Array of literal-values [boolean, number, string] 
      const type1 = [ true, 1, "true" ];
      
      // 2] Array of literal-structures [array, object]
      const type2 = [ [], {} ];
      
      // 3] Array of prototype-objects [function]
      const type3 = [ function [] {}, function [] {} ];
      
      4 và hiệu suất cao hơn so với
      // 1] Array of literal-values [boolean, number, string] 
      const type1 = [ true, 1, "true" ];
      
      // 2] Array of literal-structures [array, object]
      const type2 = [ [], {} ];
      
      // 3] Array of prototype-objects [function]
      const type3 = [ function [] {}, function [] {} ];
      
      6.
function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}

Vì vậy, để trả lời câu hỏi ...

Câu hỏi

var arr1 = ['a','b','c'];
var arr2 = arr1;

Tôi nhận ra rằng ARR2 đề cập đến cùng một mảng với ARR1, thay vì một mảng mới, độc lập. Làm thế nào tôi có thể sao chép mảng để có được hai mảng độc lập?

Câu trả lời

// 1] Array of literal-values [boolean, number, string] 
const type1 = [ true, 1, "true" ];

// 2] Array of literal-structures [array, object]
const type2 = [ [], {} ];

// 3] Array of prototype-objects [function]
const type3 = [ function [] {}, function [] {} ];
7 là một loạt các giá trị theo nghĩa đen [boolean, số hoặc chuỗi], bạn có thể sử dụng bất kỳ kỹ thuật sao chép sâu nào được thảo luận ở trên, trong đó slice[] và lây lan ____10 có hiệu suất cao nhất.

arr2 = arr1.slice[];
arr2 = [...arr1];
arr2 = arr1.splice[0];
arr2 = arr1.concat[];
arr2 = JSON.parse[JSON.stringify[arr1]];
arr2 = copy[arr1]; // Custom function needed, and provided above
arr2 = _.cloneDeep[arr1]; // Lo-dash.js needed
arr2 = jQuery.extend[true, [], arr1]; // jQuery.js needed

Khi chúng ta cần sao chép một mảng, chúng ta thường sử dụng lát cắt. Nhưng với ES6, bạn cũng có thể sử dụng toán tử lây lan để nhân đôi một mảng. Khá tiện lợi, phải 🤩

# Tại sao tôi có thể sử dụng
function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}
0 để sao chép một mảng?

Bởi vì các mảng trong JS là các giá trị tham chiếu, vì vậy khi bạn cố gắng sao chép nó bằng

function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}
0, nó sẽ chỉ sao chép tham chiếu vào mảng gốc chứ không phải giá trị của mảng. Để tạo một bản sao thực của một mảng, bạn cần sao chép giá trị của mảng theo một biến giá trị mới. Bằng cách đó, mảng mới này không tham chiếu đến địa chỉ mảng cũ trong bộ nhớ.

# Sự cố với các giá trị tham chiếu

Nếu bạn từng xử lý Redux hoặc bất kỳ khung quản lý nhà nước nào. Bạn sẽ biết tính bất biến là siêu quan trọng. Hãy để tôi giải thích ngắn gọn. Một đối tượng bất biến là một đối tượng nơi trạng thái không thể được sửa đổi sau khi nó được tạo. Vấn đề với JavaScript là

function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}
2 có thể thay đổi. Vì vậy, điều này có thể xảy ra:

Đó là lý do tại sao chúng ta cần sao chép một mảng:

# Có thể thay đổi so với các loại dữ liệu bất biến

Mutable:

  • sự vật
  • mảng
  • function

Immutable:

Tất cả các nguyên thủy là bất biến.

  • sợi dây
  • con số
  • boolean
  • null
  • chưa xác định
  • Biểu tượng

# Chỉ bản sao nông

Xin lưu ý

function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}
3 chỉ đi sâu một cấp khi sao chép một mảng. Vì vậy, nếu bạn đang cố gắng sao chép một mảng đa chiều, bạn sẽ phải sử dụng các lựa chọn thay thế khác.

Đây là một điều thú vị tôi học được. Bản sao nông có nghĩa là cấp độ đầu tiên được sao chép, mức độ sâu hơn được tham chiếu.referenced.

#
function copy[aObject] {
  // Prevent undefined objects
  // if [!aObject] return aObject;

  let bObject = Array.isArray[aObject] ? [] : {};

  let value;
  for [const key in aObject] {

    // Prevent self-references to parent object
    // if [Object.is[aObject[key], aObject]] continue;
    
    value = aObject[key];

    bObject[key] = [typeof value === "object"] ? copy[value] : value;
  }

  return bObject;
}
4 là một cách khác để nhân bản mảng

_Thanks: @hakankaraduman_

  • _@hakankaraduman: _ Vâng, tôi cố gắng không sử dụng lây lan, nó làm tôi bối rối khi đọc mã vì nó làm hai việc, lan truyền hoặc thu thập theo ngữ cảnh

  • CJ J: Tôi nghĩ rằng cách tốt nhất là cách phù hợp nhất với ngữ nghĩa của hoạt động. Tôi thích sử dụng

    function copy[aObject] {
      // Prevent undefined objects
      // if [!aObject] return aObject;
    
      let bObject = Array.isArray[aObject] ? [] : {};
    
      let value;
      for [const key in aObject] {
    
        // Prevent self-references to parent object
        // if [Object.is[aObject[key], aObject]] continue;
        
        value = aObject[key];
    
        bObject[key] = [typeof value === "object"] ? copy[value] : value;
      }
    
      return bObject;
    }
    
    4

# Tài nguyên

  • MDN Web Docs - nguyên thủy
  • Tài liệu web MDN - Cú pháp lan truyền
  • MDN Web Docs - Slice
  • Stack Overflow: Tại sao một yếu tố lan truyền không phù hợp để sao chép các mảng đa chiều?

Làm thế nào để bạn sao chép một mảng mà không có tài liệu tham khảo?

Để tạo một bản sao thực của một mảng, bạn cần sao chép giá trị của mảng theo một biến giá trị mới. Bằng cách đó, mảng mới này không tham chiếu đến địa chỉ mảng cũ trong bộ nhớ.copy over the value of the array under a new value variable. That way this new array does not reference to the old array address in memory.

Làm thế nào để bạn sao chép một mảng trong JavaScript?

Sử dụng Concat Phương pháp này là một cách phổ biến khác để sao chép một mảng trong JavaScript.Concat là một phương pháp rất hữu ích để hợp nhất hai điều khác nhau.Theo cách này, chúng tôi lấy một mảng trống và nối mảng ban đầu vào nó.Nó tạo ra một bản sao mới của mảng. This method is another popular way to copy an array in Javascript. Concat is a very useful method to merge two iterable. In this way, we take an empty array and concatenate the original array into it. It creates a fresh copy of the array.

Làm thế nào để bạn sao chép một mảng mà không thay đổi mảng gốc?

Để tạo bản sao hoặc bản sao của mảng, chúng ta có thể sử dụng toán tử lây lan hoặc phương thức splice.Các bước: Tạo bản sao của mảng bằng toán tử lây lan hoặc phương thức lát cắt.Áp dụng phương thức Splice trên mảng nhân bản và trả về mảng được trích xuất.use the spread operator or splice method. Steps : Create the clone of the array using the spread operator or slice method. apply the splice method on the cloned array and return the extracted array.

Làm cách nào để sao chép nội dung của một mảng?

Methods:..
Lặp lại từng phần tử của mảng gốc đã cho và sao chép một phần tử tại một thời điểm ..
Sử dụng phương thức Clone [] ..
Sử dụng phương thức ArrayCopy [] ..
Sử dụng phương thức copyof [] của lớp mảng ..
Sử dụng phương thức copyofrange [] của lớp mảng ..

Bài Viết Liên Quan

Chủ Đề