모던 자바스크립트 Deep Dive 정리 객체 부분

김민찬·2022년 6월 20일
0

DeepDive

목록 보기
4/6
post-thumbnail

객체

객체라는 단어 자체가 무슨 느낌인지 잘 감이 안온다. 객체는 메소드와 데이터의 묶음이라고 할 수 있다. 객체를 한자로 뜯어보면, 손 객자에 몸 체 인데 결국 어떤 물건 사물을 말하는 것이라 이해할 수 있다.

객체는 프로퍼티의 개수가 정해져 있지 않고 동적으로 추가/삭제할 수 있다. 프로퍼티의 값에도 제약이 없다. 객체는 복합적인 자료 구조이므로, 관리하는 방식이 원시값과 다르게 복잡하고 구현방식도 브라우저마다 다를 수 있다.

  • 자료구조?
    효율적인 접근 및 수정을 가능하게 하는 자료의 조직, 관리, 저장을 의미한다. 자바 스크립트 객체는 key와 value로 데이터를 저장하는 자료구조인 해시테이블로 생각할 수 있다. 하지만 클래스 없이 생성하고, 동적으로 프로퍼티와 메서드를 추가할 수 있다는 점에서 차이가 있다. 이는 편리하지만, 성능면에서는 생성과 프로퍼티 접근에 비용이 많이 드는 비효율적인 방식이다.

V8 자바스크립트 엔진에서는 성능을 보장하기 위해 히든 클래스라는 방식을 사용하고 있다.

  • 히든 클래스?
    객체를 만들 때 히든클래스라는 객체를 생성하여 오프셋 정보를 저장하는 것

* 오프셋..?

세그먼트에 대한 상대 주소

* 세그먼트..?!???

메모리 구분을 위해 사용되는 주소
.
.
.
(무슨 말인지 모르겠다. 뒤돌아 나간다.)

객체를 생성하고 프로퍼티에 접근하는 것도 원시 값과 비교할 때 비용이 많이 드는 일이다. 따라서 객체는 원시 값과는 다른 방식으로 동작하도록 설계되어 있다.

변경 가능한 값

원시값을 할당한 변수가 기억하는 메모리 주소를 통해 공간에 접근하면, 원시 값에 접근할 수 있다. 객체는 메모리 공간에 접근하면 참조 값(객체가 저장된 메모리 공간의 주소)에 접근된다.

(값에 또 주소가 있었다.)(객체의 할당)

원시 값을 할당한 변수를 참조하면 메모리에 저장되어 있는 원시값에 접근한다. 하지만 객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근한다.

그래서 객체를 할당한 변수는 객체를 참조한다, 객체를 가리키고 있다라고 표현한다. 앞장에서 살펴본 것 처럼 원시 값은 변경 불가능한 값이라 값을 변경하기 위해서는 재할당해줘야 한다.

객체는 변경 가능한 값이다. 재할당없이 동적으로 추가하거나, 프로퍼티 값을 갱신/삭제할 수 있다.

원시 값이었다면 변경을 위해 재할당을 통해서 메모리에 원시 값을 새롭게 생성한다. 객체는 재할당을 하지 않고 변경이 가능하니, 변수의 참조값은 변경되지 않는다.

객체는 크기가 일정하지 않고, 프로퍼티 값이 객체인 경우 복사 생성 비용이 많이 든다. 효율적인 소비가 어렵고, 성능이 나빠진다. 이는 효율적인 접근/수정을 가능하게 하는 자료구조라고 하기 어려울 수 있다.

따라서 자바 스크립트 객체는 메모리를 효율적으로 사용하기 위해서, 새로 생성하는 비용을 절약해서 성능을 향상시키기 위해 변경 가능한 값으로 설계되어 있다.

이는 효율성과 성능을 위해 어느정도 구조적 단점을 감안한 설계이다. 이런 구조는 부작용이 있는데, 여러개의 식별자가 하나의 객체를 공유할 수 있다는 것이다.

참조에 의한 전달

객체를 가리키는 변수(원본)을 다른 변수(사본)에 할당하면, 원본의 참조 값이 복사되어 전달된다. 그러면 사본에는 원본이 가지고 있던 참조값을 갖게 되고, 결과적으로 동일한 객체를 가리키게 된다.

이 것은 두 개의 식별자가 하나의 객체를 공유한다는 것을 의미한다. 따라서, 원본 또는 사본 중 어느 한쪽에서 객체를 변경하면, 서로 영향을 받는다.

결국 값에 의한 전달과 참조에 의한 전달은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달하는 면에서 동일하다.

다만 식별자가 기억하는 메모리 공간, 즉 변수에 저장되어 있는 값이 원시 값이냐, 참조 값이냐의 차이만 있을 뿐이다. 따라서 자바스크립트에는 참조에 의한 전달은 존재하지 않고, 값에 의한 전달만이 존재한다고 말할 수 있다.

자바스크립트의 이 동작을 설명하는 정확한 용어는 존재하지 않는다. 공유에 의한 전달이라 표현하는 경우도 있지만 공식적인 용어가 아니고, 정확히 설명하지 못한다.

다만 여기서는 전달되는 값의 종류가 원시 값인지, 참조 값인지 구별하기 위해 값에 의한 전달과 참조에 의한 전달로 구분하기로 한다.

자바스크립트는 포인터가 존재하지 않기 때문에 다른 언어에서의 참조에 의한 전달과 의미가 정확하게 일치하지는 않는다.

  • 포인터?

메모리의 주소값을 저장하는 변수를 포인터라고 한다.


참고

모던자바스크립트 DeepDive

https://ko.wikipedia.org/wiki/%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0

https://darozzang.tistory.com/entry/%EC%A0%88%EB%8C%80%EC%A3%BC%EC%86%8C-%EC%84%B8%EA%B7%B8%EB%A8%BC%ED%8A%B8-%EC%98%A4%ED%94%84%EC%85%8B

https://engineering.linecorp.com/ko/blog/v8-hidden-class/

profile
프론트엔드 개발자로 나아가고 있는 김민찬입니다.

0개의 댓글