HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
프로그래머스 프론트엔드 데브코스 2기
프로그래머스 프론트엔드 데브코스 2기
/
📰
CS 스터디
/
자바스크립트 & 히든 클래스
자바스크립트 & 히든 클래스
자바스크립트 & 히든 클래스

자바스크립트 & 히든 클래스

V8 Object property 저장 방식

V8에서 객체라면( key가 string | sybol ) Properties라는 별도의 배열 구조에 속성들을 저장합니다. 이 때 배열과 달리 key로 Properties 내 속성의 위치를 파악할 수 없습니다. (key ≠ index)
notion image
Named properties are stored in a similar way in a separate array. However, unlike elements, we cannot simply use the key to deduce their position within the properties array; we need some additional metadata.
그래서 속성의 위치를 메모리에 저장하는데, 이를 컴파일 시 알 수 없습니다.
 

다른 언어는?

정적 타입은 컴파일 시 속성의 위치를 알 수 있다!
정적타입 언어들은 컴파일 시 타입이 결정되기에 속성의 메모리 위치를 실행 전에 결정할 수 있습니다. 하지만 자바스크립트는 런타임 시 객체의 속성이 동적으로 변하기에 그럴 수 없습니다.
 

그럼 속성의 메모리 위치를 어떻게 찾지?

속성 위치 따로 저장 + 동적 탐색
이를 해결하기 위해 자바스크립트는 딕셔너리와 유사한 구조로 속성의 위치를 메모리에 저장합니다.
 
동적 조회가 필요해 성능 저하
하지만, 한 가지 문제가 있습니다. 자바스크립트가 동적 타입의 언어라는 점입니다. 자바스크립트는 객체가 생성된 이후에도 속성을 추가하거나 삭제할 수 있기 때문에 속성의 위치가 광범위해질 수 밖에 없습니다. 이렇게 범위가 넓다면 크기가 지정된 다른 언어들에 비해 탐색 범위가 넓어서 비효율적일 수 밖에 없습니다.
 

히든 클래스

객체 모양, 속성을 인덱스로 저장, 인라인 캐싱
이를 해결하기 위해 자바스크립트 엔진(V8)은 히든 클래스를 사용합니다. 히든 클래스는 정적타입 언어에서 사용하는 고정 객체 레이아웃과 유사하게 작동합니다. 다만, 런타임에 생성된다는 차이가 있습니다.

예시

예를 들어 Student라는 생성자함수로 kid라는 인스턴스를 만들어보면 다음과 같은 순서로 진행됩니다.
  1. new Student('happy',18)가 실행되는 시점, 아직 this.name = name을 읽어들이기 전 인스턴스는 빈 객체 {}
  1. this.name = name이 수행되면 name: ‘happy’를 객체에 추가
  1. this.age = age이 수행되면 age: 18을 객체에 추가
 

여기서 히든클래스가 어떻게 사용되는가?

히든 클래스엔 Transition Table, Property Table이 존재합니다.
  • Transition Table
    • 이정표, 전환 정보를 담고 있어서 특정 property가 추가되면 어떤 히든 클래스로 이동해야되는 지 알 수 있다. 런타임 시 필드 구조가 변할 때 생성, 포인터로 클래스 전환
    • 전환정보 : 새로운 히든 클래스가 생성되고 해당 클래스를 참조하게 되면 이전 클래스에 어떤 프로퍼티로 해당 전환이 일어났는지 기록
  • Property Table
    • property의 메모리 위치 기록, offset의 값에 속성 값 기록
notion image
  1. 오프셋 없이 히든 클래스 생성 (HiddenClass0),
    1. ⇒ kid는 HiddenClass0 참조
  1. HiddenClass0을 상속받은 자식 HiddenClass1의 오프셋 0에 name 프로퍼티 할당
    1. ⇒ kid는 HiddenClass1 참조
      ⇒ HiddenClass0에 전환정보담기( name을 추가하면 HiddenClass1로 전환된다.)
  1. HiddenClass1을 상속받은 자식 HiddenClass2의 오프셋 1에 age 프로퍼티 할당
    1. ⇒ kid는 HiddenClass2 참조
      ⇒ HiddenClass1에 전환정보담기( age를 추가하면 HiddenClass2로 전환된다.)
       

쉬운 비유법

광교 찾아가기
지역을 속성, 해당 지역 찾아가기를 속성의 메모리 주소 찾기라고 생각해보겠습니다. 이 때 hiddenClass는 길 찾기 정보가 될 것입니다.
hiddenClass 길 찾기 정보가 없이 여러분에게 광교로 오라고 하면, 찾기가 어렵습니다. 반면, 여러분이 사는 곳에서 광교로 오는 신분당선 hiddenClass 정보가 있다면 쉽게 찾아 올 수 있습니다.
 

히든 클래스 최적화

덕분에 새로운 Student 인스턴스를 만들 때도 새로 히든 클래스를 만드는 게 아니라 기록된 전환 정보를 따라 클래스를 참조해 자원 낭비를 최소화할 수 있습니다.
 

인라인 캐싱

객체 접근 시 조회 작업 생략
이전에 조회했던 오프셋을 캐싱해 특정 프로퍼티의 메모리주소로 바로 이동할 수 있게 하는 최적화 방식입니다.
  • 예) name 프로퍼티 실제 메모리 주소 위치를 offset에 저장 ⇒ offset에 저장된 위치로 바로 이동
 

주의: 인라인 캐싱이 안되는 경우

복잡한 지하철 노선도 + 길찾기 어플이 없다면?
인스턴스의 구조가 동일하지 않다면 각각 히든 클래스를 따로 만들기 때문에 인스턴스의 속성값을 비교해야 되서 속성 조회작업을 생략할 수 없습니다.
 
따라서 인스턴스의 구조를 동일하게 짜도록 해야 좋습니다.
 
 
Map - JavaScript | MDN
The object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value. Map objects are collections of key-value pairs. A key in the Map may only occur once; it is unique in the Map's collection.
Map - JavaScript | MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
Map - JavaScript | MDN
Fast properties in V8
In this blog post we would like to explain how V8 handles JavaScript properties internally. From a JavaScript point of view there are only a few distinctions necessary for properties. JavaScript objects mostly behave like dictionaries, with string keys and arbitrary objects as values.
Fast properties in V8
https://v8.dev/blog/fast-properties
Fast properties in V8
V8 엔진에 대해서
javaScript 엔진 - server, client 모두 사용 가능. - 최초에는 JS의 성능을 높이기 위해 고안 - JS코드 -> 바로 기계어로 적용 (중간어(바이트 코드)를 만들지 않는다. ) SpiderMonkey나 Mozilla같은 많은 JS엔진처럼 JIT 컴파일러를 사용하며, V8의 가장 큰 차이점은 중간언어를 만든지 않는다는 것. - 미리 가능한 많은 코드를 함수 호출 지점에 호출된 함수의 내용을 바꾸는 과정.
V8 엔진에 대해서
https://lee33398.tistory.com/32
V8 엔진에 대해서
객체에 프로퍼티 설정 시 성능 이슈
발생일: 2018.09.19 키워드: json, object, Map 문제: 배치 작업에서 약 천만 행의 데이터를 로드에 객체의 프로퍼티로 할당하는 작업을 진행하고 있었다. 대략 다음과 같이 DB에서 데이터를 읽어와 메모리에 할당..
객체에 프로퍼티 설정 시 성능 이슈
https://ohgyun.com/764
객체에 프로퍼티 설정 시 성능 이슈
제발 한국인이라면 자바스크립트 Object를 Map 처럼 사용하지 맙시다.
오늘 코딩하던 중에 Javascript 에서 만든 Map을 Controller 쪽으로 어떻게 넘길지에 대해 고민 하는 일이 있었습니다. JavaScript 에서는 Object 를 사용하면 왠만하면 다른 언어에서의 Map 과 유사하게 사용 할 수 있기 때문에 딱히 Map을 사용 해 본 적이 없었는데요. 특히 나중에 자바에서 스프링 부트에서 제공하는 JsonParser 를 이용하면 JSON 데이터를 List 아니면 Map 으로 Parsing을 하더라고요.
제발 한국인이라면 자바스크립트 Object를 Map 처럼 사용하지 맙시다.
https://shanepark.tistory.com/220
제발 한국인이라면 자바스크립트 Object를 Map 처럼 사용하지 맙시다.
자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁
몇 주 전 우리는 자바스크립트를 좀 더 깊이 살펴 보고 실제로 어떻게 작동하는지 알아보는 시리즈를 시작했습니다. 이 시리즈의 동기는 자바스크립트가 무엇으로 구성되어 있고 그 구성요소가 어떻게 맞물려 작동하는지 더 잘 알면 더 나은 코드와 앱을 작성할 수 있다는 생각이었습니다. 시리즈의 첫 번째 글은 엔진, 런타임, 콜스택의 개관에 초점을 맞췄습니다. 이...
자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁
https://engineering.huiseoul.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%ED%95%98%EB%8A%94%EA%B0%80-v8-%EC%97%94%EC%A7%84%EC%9D%98-%EB%82%B4%EB%B6%80-%EC%B5%9C%EC%A0%81%ED%99%94%EB%90%9C-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EB%8B%A4%EC%84%AF-%EA%B0%80%EC%A7%80-%ED%8C%81-6c6f9832c1d9
자바스크립트는 어떻게 작동하는가: V8 엔진의 내부 + 최적화된 코드를 작성을 위한 다섯 가지 팁
자바스크립트 성능의 비밀 (V8과 히든 클래스)
자바스크립트가 C++ 성능에 도달한 방법 원문 : https://blog.bitsrc.io/secret-behind-javascript-performance-v8-hidden-classes-ba4d0ebfb89d 오늘날 자바스크립트는 웹 개발에서 가장 많이 사용되는 언어 중 하나가 되었다. 그러나 이 단계까지 오기 위해서 많은 장애물을 통과해야 한다. 이런 목표 중 하나는 C++과 같은 언어와 유사한 성능으로 실행 속도를 달성했다는 것이다. V8 자바스크립트 엔진의 발명 없이는 이 중 어느 것도 불가능하다.
자바스크립트 성능의 비밀 (V8과 히든 클래스)
https://ui.toast.com/posts/ko_20210909
자바스크립트 성능의 비밀 (V8과 히든 클래스)
V8의 히든 클래스 이야기
안녕하세요? LINE Fukuoka의 프론트엔드 엔지니어 Yonehara입니다. 저는 프론트엔드 개발자로서 아직 웹 브라우저나 자바스크립트의 기분을 헤아려줄 만큼의 경지에는 올라가지 못했다고 생각합니다. 이로 인해 저희 서비스 사용자에게 원하는 만큼의 쾌적한 UX를 제공해 드리지 못할 때가 있어 괴로울 때가 있습니다. 그나마 다행인 것은, 우리가 이 자바스크립트의 속마음을 상당 부분 분석적으로 들여다볼 수 있다는 점입니다.
V8의 히든 클래스 이야기
https://engineering.linecorp.com/ko/blog/v8-hidden-class/
V8의 히든 클래스 이야기
 
팀
끝
발표자
발표일
Oct 30, 2022
발표방법
당일 라이브
function Student(name,age){ this.name = name this.age = age } let kid = new Student('happy',18)
function Student(name,age){ this.name = name this.age = age } let kid = new Student('happy',18)// name, age는 인라인 캐싱 가능 let kid2 = new Student('sad',19) kid.grade = 'A' // 인라인 캐싱 안돼 kid.gender = 'M' // 인라인 캐싱 안돼