【问题标题】:Assigning to variable sliced array allows modify original array分配给可变切片数组允许修改原始数组
【发布时间】:2018-02-10 06:20:15
【问题描述】:

我们有一个拥有私有数组的类。

class BookService{
   private booksList: Book[];

   constructor (){
      this.booksList = [
         new Book('Tales', true),
         new Book('Novels', false),
         new Book('Dictionary', false)
      ];
   }

   getBooks(){
      return this.booksList;
   }

}

class Book{
   constructor ( public name: string, public isRead: boolean ){}
}

export const bookService =  new BookService();

我们也有一个实现。

import {bookService} from './book-service';

//get copy of original array which is not by reference
let books: any = bookService.getBooks().slice(0);
//log local array
console.log(books);

// modify local array
books[1].isRead = true;

//log original array
console.log(bookService.getBooks());

我们得到了原始数组的副本。然后我们修改了本地数组(原始数组的副本)。我们得到了被修改的原始数组。

我不明白为什么原始私有数组被修改了?

如果我将 getBooks 修改为

  getBooks(){
     return this.booksList.slice(0);
  }

没用。

如果我使用 lodash 方法修改 getBooks _.cloneDeep Method description

  getBooks(){
     return _.cloneDeep(this.booksList);
  }

原始数组不会被修改。 为什么?如何避免与此类情况相关的错误?

【问题讨论】:

标签: javascript arrays typescript lodash pass-by-reference


【解决方案1】:

当您使用slice 克隆数组时,里面的对象保持不变。

如果您在数组arr 中有三个对象abc,并且您将其克隆,则新数组仍将包含对abc 的引用,而不是看起来相同的新对象。

var arr = [ a, b, c ];
var arr2 = arr.slice(0); // [ a, b, c ];

arr === arr2; // false - they are not the same array

arr[0] === arr2[0]; // true - they contain the same a object

这意味着,如果您从 arr2 获得 a,则它与 arr 中的 a 对象相同 - 因此修改一个对象会同时修改两者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2018-07-30
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    相关资源
    最近更新 更多