JavaScript及V8引擎中值的数据类型存储位置与方式咨询
Great question—let's start with the general JavaScript rules before digging into how V8 specifically handles this.
1. General JavaScript Value Storage
JavaScript splits values into two core categories, and their storage locations work very differently:
Primitive Types (7 total: string, number, boolean, null, undefined, symbol, bigint)
These are value types, meaning their actual values are stored directly in the call stack. The stack is a fast, fixed-size memory region where the engine tracks execution contexts and small, predictable-size data.
When you assign a primitive to a variable, you copy the entire value. For example:
let score = 95; let scoreCopy = score; scoreCopy = 100; console.log(score); // Still 95—scoreCopy has its own separate value
Even strings (which can feel "large") are treated as primitives here. While some engines optimize long strings to live in the heap, the JS spec defines them as immutable value types—any string operation creates a new string, not modifies the original.
Object Types (including arrays, functions, custom objects, and primitive wrapper objects)
These are reference types. The actual object data lives in the heap—a larger, dynamic memory region for data that can grow or change size. The stack only stores a pointer (a memory address) pointing to the object's location in the heap.
When you assign an object to another variable, you copy the pointer, not the object itself. So both variables reference the same heap object:
let car = { make: "Toyota" }; let carRef = car; carRef.make = "Honda"; console.log(car.make); // Honda—both variables point to the same object
2. V8 Engine-Specific Storage
V8 (the engine powering Chrome, Node.js, etc.) has optimized memory management, so let's break down its specific handling:
Primitive Types in V8
- Small, fixed-size primitives (number, boolean, undefined, symbol, bigint) are stored directly in stack frames. For example, a 64-bit number takes exactly 8 bytes, which fits neatly in the stack's structured memory.
- Strings: Short strings (usually under ~256 characters) stay in the stack. Longer strings get moved to the heap, but V8 uses string interning—reusing memory for identical strings—to save space. When you call a method on a string (like
str.toUpperCase()), V8 temporarily creates aStringwrapper object in the heap, runs the method, then discards the wrapper right away. - Null: Even though it's a primitive, V8 represents null as a special empty pointer. But from a JS perspective, it's still treated as a value type.
Object Types in V8
All objects (arrays, functions, wrapper objects like new String("hello"), etc.) live in the heap, which V8 splits into specialized regions for efficient garbage collection:
- New Space: For small, short-lived objects. V8 uses a fast "Scavenger" garbage collection algorithm here to quickly clean up unused objects.
- Old Space: For objects that survive multiple garbage collection cycles in New Space—these are considered "long-lived."
- Large Object Space: For objects too big to fit in New or Old Space (like huge arrays). They're stored separately to avoid disrupting garbage collection for smaller objects.
Just like in general JS, the stack stores pointers to these heap objects. When you pass an object to a function, you're passing the pointer, not the entire object.
内容的提问来源于stack exchange,提问作者Magnus

