O V8 otimiza JavaScript compilando para código nativo via JIT. Duas técnicas são centrais: Hidden Classes e Inline Caching.
Hidden Classes
Quando você cria um objeto, o V8 atribui uma hidden class (ou map) a ele. Propriedades acessadas no mesmo shape compartilham a mesma classe:
function Point(x, y) {
this.x = x; // hidden class: C1
this.y = y; // hidden class: C2 (transição de C1)
}
const a = new Point(1, 2);
const b = new Point(3, 4); // MESMA hidden class = otimizado
Agora, quebre o shape e o V8 desiste:
const a = new Point(1, 2);
a.z = 3; // nova propriedade depois da criação = shape diferente
Cada shape diferente força o V8 a desotimizar. Em loops com milhares de objetos, o custo é real.
Inline Caching
Quando você acessa obj.prop num loop, o V8 cachead o resultado da lookup. Se o shape do objeto muda entre iterações, o cache é invalidado:
// Ruim: shapes misturados no mesmo array
const items = [
{ x: 1, y: 2 },
{ x: 3, y: 4, extra: true }, // shape diferente!
];
// Bom: shapes consistentes
const items = [
{ x: 1, y: 2, extra: false },
{ x: 3, y: 4, extra: true },
];
Na prática
- Sempre inicialize propriedades no construtor — mesmo com
nullouundefined - Não adicione propriedades depois — prefira objetos separados
- Monotipifique arrays — não misture tipos num mesmo array
- Prefira classes a dicionários genéricos quando o shape é fixo
// Prefira
class User {
constructor(name) {
this.name = name;
this.role = "viewer";
}
}
// Evite
function createUser(name) {
return { name, role: "viewer" };
}
// (classes são otimizadas consistentemente)