Skip to content

Commit 281363b

Browse files
committed
feat(i18n): translate JavaScript chapter 7 V8 internals lessons to English
1 parent 93c0890 commit 281363b

3 files changed

Lines changed: 454 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
{
2+
"lessonId": "js-7-1",
3+
"title": "V8 Hidden Classes (Shapes)",
4+
"concept": "The V8 engine uses an internal map called a 'Hidden Class' to speed up property access on objects.",
5+
"content": {
6+
"code": "function Point(x, y) {\n this.x = x;\n this.y = y;\n}\n\nconst p1 = new Point(1, 2);\nconst p2 = new Point(3, 4);\n\n// p1에 새로운 속성 추가 (히든 클래스 변경 발생!)\np1.z = 5;\n\nconsole.log(p1.x, p1.z);\nconsole.log(p2.x);",
7+
"steps": [
8+
{
9+
"title": "Creating p1: hidden class creation",
10+
"explanation": "When `new Point(1, 2)` runs, the V8 engine creates a `Hidden Class` to remember the 'shape' of this object.\nEach time a property is added, the object transitions to a new hidden class.\n1. A hidden class C0 is created for the empty object\n2. `this.x = 1` causes a transition from C0 to C1 (x added)\n3. `this.y = 2` causes a transition from C1 to C2 (y added)\n`p1` ends up with hidden class C2.",
11+
"keyInsight": "Adding a property isn't just 'storing a value' — it triggers an internal structure change (Transition).",
12+
"visualizationType": "memory",
13+
"memoryState": {
14+
"stack": [
15+
{
16+
"name": "p1",
17+
"value": "→ 0x001"
18+
}
19+
],
20+
"heap": [
21+
{
22+
"address": "0x001",
23+
"content": "{ x: 1, y: 2 }",
24+
"label": "HiddenClass: C2"
25+
}
26+
]
27+
},
28+
"code": "const p1 = new Point(1, 2);"
29+
},
30+
{
31+
"title": "Creating p2: reusing the hidden class",
32+
"explanation": "When creating `p2`, V8 notices that the property addition order and structure are identical to `p1`.\nSo instead of creating a new hidden class, it reuses the C2 hidden class that `p1` already established.\nThis makes property access very fast.",
33+
"keyInsight": "Initializing properties in the same order lets the engine treat objects as the 'same type' and optimize them.",
34+
"visualizationType": "memory",
35+
"memoryState": {
36+
"stack": [
37+
{
38+
"name": "p2",
39+
"value": "→ 0x002"
40+
}
41+
],
42+
"heap": [
43+
{
44+
"address": "0x001",
45+
"content": "{ x: 1, y: 2 }",
46+
"label": "HiddenClass: C2"
47+
},
48+
{
49+
"address": "0x002",
50+
"content": "{ x: 3, y: 4 }",
51+
"label": "HiddenClass: C2 (Shared)"
52+
}
53+
]
54+
},
55+
"code": "const p2 = new Point(3, 4);"
56+
},
57+
{
58+
"title": "Adding a property: hidden class branch",
59+
"explanation": "After object creation, we dynamically add the `z` property to `p1` only.\nSince the existing C2 hidden class has no information about `z`, V8 creates a new hidden class C3 (C2 + z) and transitions `p1` to C3.\nNow `p1` and `p2` have different hidden classes, reducing optimization efficiency.",
60+
"keyInsight": "Dynamically adding properties after object creation is the main culprit for breaking optimization.",
61+
"visualizationType": "memory",
62+
"memoryState": {
63+
"heap": [
64+
{
65+
"address": "0x001",
66+
"content": "{ x: 1, y: 2, z: 5 }",
67+
"label": "HiddenClass: C3",
68+
"warning": "Shape Changed"
69+
},
70+
{
71+
"address": "0x002",
72+
"content": "{ x: 3, y: 4 }",
73+
"label": "HiddenClass: C2"
74+
}
75+
]
76+
},
77+
"code": "p1.z = 5;"
78+
},
79+
{
80+
"title": "Printing p1 properties",
81+
"explanation": "Printing `p1`'s `x` and `z` properties.\n`p1` uses the new hidden class C3 to locate the values.",
82+
"visualizationType": "memory",
83+
"memoryState": {
84+
"output": [
85+
"1 5"
86+
]
87+
},
88+
"code": "console.log(p1.x, p1.z);"
89+
},
90+
{
91+
"title": "Printing p2 properties",
92+
"explanation": "Printing `p2`'s `x` property.\n`p2` still uses the original hidden class C2.",
93+
"visualizationType": "memory",
94+
"memoryState": {
95+
"output": [
96+
"1 5",
97+
"3"
98+
]
99+
},
100+
"code": "console.log(p2.x);"
101+
}
102+
]
103+
},
104+
"quiz": {
105+
"question": "What is the best practice for maintaining V8's Hidden Class optimization?",
106+
"options": [
107+
"Initialize all properties in order inside the constructor",
108+
"Add properties on the fly whenever needed (obj.newProp = 1)",
109+
"Change the property initialization order each time (x, y → y, x)",
110+
"Frequently delete properties with the delete operator"
111+
],
112+
"correctIndex": 0,
113+
"explanation": "Defining properties in order inside the constructor ensures all created objects share the same hidden class, giving you the best performance."
114+
},
115+
"misconceptions": [
116+
{
117+
"wrong": "JavaScript objects are HashMaps, so they're slow",
118+
"correct": "V8 uses hidden classes to access properties as fast as **array offsets**.",
119+
"why": "Early JS engines used hash maps, but modern V8 introduced hidden classes to achieve property access speeds comparable to statically typed languages like C++ and Java."
120+
}
121+
],
122+
"keyTakeaway": "Keep your objects' 'shape' consistent. Consistency is speed."
123+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"lessonId": "js-7-2",
3+
"title": "V8 Memory Structure (Generations)",
4+
"concept": "V8 divides objects into 'Young Generation (new)' and 'Old Generation (long-lived)' for efficient memory management.",
5+
"content": {
6+
"code": "// 1. Young Generation (단명 객체)\nfunction createTemp() {\n const temp = { id: Math.random() };\n // 함수 종료 시 참조가 끊기며 GC 대상이 됨\n}\n\n// 2. Old Generation (장수 객체)\nconst cache = [];\nfunction save(data) {\n cache.push(data); // 전역 배열이 참조를 유지함\n}\n\ncreateTemp(); // Young 영역에 할당되었다가 금방 수거됨\ncreateTemp();\n\nsave({ type: 'important' }); // GC를 여러 번 버티면 Old 영역으로 승격됨",
7+
"steps": [
8+
{
9+
"title": "Object creation (Young Generation)",
10+
"explanation": "When `createTemp()` is called, the `temp` object inside is allocated in the **Young Generation** area of the V8 heap.\nMost objects spend only a brief life here.",
11+
"keyInsight": "The Young Generation is where 'newborn' objects live — GC here is very fast.",
12+
"visualizationType": "memory",
13+
"memoryState": {
14+
"heap": [
15+
{
16+
"content": "{id: ...}",
17+
"address": "Young"
18+
}
19+
]
20+
},
21+
"code": "createTemp(); // Young 영역에 할당되었다가 금방 수거됨",
22+
"highlightOffset": [
23+
0,
24+
-11,
25+
-10
26+
]
27+
},
28+
{
29+
"title": "Minor GC (Scavenge)",
30+
"explanation": "When `createTemp()` finishes, the `temp` object is no longer referenced and becomes 'garbage'.\nThe **Minor GC (Scavenge)** that sweeps the Young Generation collects it very quickly.",
31+
"visualizationType": "memory",
32+
"memoryState": {
33+
"heap": [
34+
{
35+
"content": "empty (collected)",
36+
"address": "Young"
37+
}
38+
]
39+
},
40+
"code": "createTemp(); // Young 영역에 할당되었다가 금방 수거됨",
41+
"highlightOffset": [
42+
0,
43+
-9
44+
]
45+
},
46+
{
47+
"title": "Repeated creation and collection",
48+
"explanation": "`createTemp()` is called again.\nJust like before, the `temp` object is created in Young Generation and disappears quickly when the function ends.",
49+
"visualizationType": "memory",
50+
"memoryState": {
51+
"heap": [
52+
{
53+
"note": "Object created and collected again",
54+
"address": "Young",
55+
"content": "note: Object created and collected again"
56+
}
57+
]
58+
},
59+
"code": "createTemp();"
60+
},
61+
{
62+
"title": "Creating a long-lived object",
63+
"explanation": "The `save` function is called, creating the `{ type: 'important' }` object and adding it to the `cache` array.",
64+
"visualizationType": "memory",
65+
"memoryState": {
66+
"heap": [
67+
{
68+
"content": "{type: 'important'}",
69+
"address": "Young"
70+
}
71+
]
72+
},
73+
"code": "save({ type: 'important' }); // GC를 여러 번 버티면 Old 영역으로 승격됨"
74+
},
75+
{
76+
"title": "Reference kept alive (promotion candidate)",
77+
"explanation": "The `cache` array is a global variable, so it lives for the entire program lifetime.\nAny object referenced by `cache` keeps surviving Minor GC cycles.\nObjects that survive multiple GC cycles are eventually 'promoted' to the **Old Generation**.",
78+
"keyInsight": "Long-lived objects are moved to a 'safe storage (Old Space)' for more efficient management.",
79+
"visualizationType": "memory",
80+
"memoryState": {
81+
"heap": [
82+
{
83+
"address": "Young",
84+
"content": "???"
85+
},
86+
{
87+
"content": "{type: 'important'}",
88+
"note": "Promoted",
89+
"address": "Old"
90+
}
91+
]
92+
},
93+
"code": "cache.push(data); // 전역 배열이 참조를 유지함"
94+
}
95+
]
96+
},
97+
"quiz": {
98+
"question": "Which statement about V8's garbage collection strategy is correct?",
99+
"options": [
100+
"All objects are initially allocated to Old Generation",
101+
"Young Generation is large and GC is slow there",
102+
"Most objects are created in Young Generation and collected quickly",
103+
"GC must be triggered manually by the developer"
104+
],
105+
"correctIndex": 2,
106+
"explanation": "Most objects become useless soon after creation (e.g., when a function returns), so it's efficient to allocate and collect them quickly in the small Young Generation."
107+
},
108+
"misconceptions": [
109+
{
110+
"wrong": "The program doesn't pause while GC is running",
111+
"correct": "It does pause (Stop-the-world).\nBut for such a short time that users never notice.",
112+
"why": "The program must pause while memory is being reorganized to avoid conflicts.\nV8 breaks this work into increments as small as 1ms (Incremental Marking), so stutter is nearly imperceptible."
113+
}
114+
],
115+
"keyTakeaway": "Memory areas are divided by object lifetime. Minimize unnecessary global variables to prevent memory leaks."
116+
}

0 commit comments

Comments
 (0)