JavaScript로 트리구조를 구현해보면서 헷갈리는 부분을 정리해보았다.
위 클래스에서 root = new Tree(1)
라는 인스턴스를 만들었다고 가정했을때, 생성자의 초기 value값이 1로 변하고 tree.add(2)
를 했을때 생성자의 초기 children 배열에 newTree 즉, 새로운 인스턴스가 저장되는 줄 알았다.
예를 들면
root.add(1)
root.add(2)
root.add(3)
를 한 후에 새로운 인스턴스를 생성하면 생성자 children 배열에 저장이 되는 줄 알았다.
완전히 잘못 생각했다.
이 사진이 완벽하진 않지만 이런식으로 생각을 하는게 맞는거 같다.
class의 생성자는 그대로 있고, 인스턴스를 만들때마다 클래스가 내장하고 있는 메소드랑 생성자를 가지고 오게된다. 그러므로 인스턴스를 만든후 아무리 add를 해도 클래스의 생성자에는 영향이 없다.
이 생각을 하게된 이유는 복제 메서드를 만들면서이다.
내 잘못된 이론대로라면 위 코드의 인스턴스를 만들고 add를 한뒤, 또 다른 인스턴스를 만들고 clone메서드를 실행 시키면 add한 부분까지 나와야한다. 위에서 했던 말이랑 같은 말이지만 나는 이 부분이 헷갈려서 한참 해맸다... 인스턴스는 클래스 내부기능을 물려받아서 만들어진 객체일뿐, 클래스 값을 변경시킬순 없다.
이렇게 되면 위에 clone메서드도 수정을 해줘야한다. clone 안에서 새로운 newTree객체를 생성하면 복제 되는게 클래스의 내장기능을 가진 새로운 인스턴스가 생길뿐이다. add를 한다고 해서 절대 클래스 값이 안바뀐다.
복제가 되는지 테스트를 해보면 전혀 복사가 되지 않고 새로운 객체 인스턴스를 리턴할 뿐이다.
위 코드를 복제 메서드로 만드려면 이렇게 바꿔주어야한다.
테스트를 해볼까?
clone메소드를 사용했을때 복제가 됨을 확인할 수 있다.
clone 메소드를 구현할때 let newTree = new Tree()
이 부분은 단지 생성자를 그대로 받아서 객체를 만드는 것이기 때문에 처음에 만들어진 인스턴스의 value값과 children값을 복제 될 인스턴스에 할당해줘야한다.
newTree.value = this.value
newTree.children = this.children
그리고 복제된 인스턴스를 리턴하기위해 리턴을 해준다.
이렇게 구구절절하게 쓰다보니 어느새 좀 더 완벽하게 이해가 되는거 같다.