0

We have a class which has a private array.

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();

Also we have an implementation.

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());

We got the copy of origin array. Then we modified local array ( copy of the origin array ). The we got origin array which was modified.

I can't understand why origin private array have been modified?

If I modify getBooks to

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

it won't help.

If I modify getBooks using the lodash method _.cloneDeep Method description

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

the original array won't be modified. Why? How to avoid mistakes which relate to this kind of situations?

  • Possible duplicate of [How do I correctly clone a JavaScript object?](https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object) – kGielo Sep 01 '17 at 08:18
  • Copying the array doesn't make a copy of the objects contained within it. – deceze Sep 01 '17 at 08:18
  • What you are doing is called a _shallow copy_. – Ram Sep 01 '17 at 08:21

1 Answers1

0

When you clone the array with slice, the objects inside remain the same.

If you have three objects, a, b and c in an array arr and you clone it, the new array will still contain references to a, b and c, rather than new objects which look the same.

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

This means that if you get a from arr2, it's the same a object that is in arr - so modifying one modifies both.

James Monger
  • 10,181
  • 7
  • 62
  • 98