completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Prototypes inside the engine

Learn how prototype maps, validity cells, and shape teleporting let engines cache inherited lookups without breaking JavaScript semantics.

By the end, you can
  • 01
    Explain the shortcut to a prototypeFollow how an engine turns obj.method into two quick checks (the object's map and a validity cell) and one read straight from the prototype that has the method.
  • 02
    Tell JavaScript rules from engine tricksSay what JavaScript promises about shadowing and prototype changes, and which parts are only tricks used inside V8 and SpiderMonkey.
  • 03
    Predict what a prototype change costsDecide whether a change turns a validity cell invalid, gives the object a new map, throws away fast code, or leaves the shortcut working.

Prototype lookup needs fast guards

Every object can have a prototype: another object it falls back on. When you read a property, JavaScript looks on the object first. If the property is not there, JavaScript looks on the prototype, then on the prototype's prototype, and so on. This line of objects is called the prototype chain.

The chain can change while a program runs. Code can add a property, replace a method, or give an object a new prototype. The JavaScript engine (the program inside the browser or Node that runs your code) must always give the right answer, even after such a change.

Definition

Prototype internals are the tricks an engine uses to find inherited properties fast. The engine saves a shortcut to the prototype that has the property. Before it uses the shortcut, it runs a few quick checks, called guards. The guards make sure the chain has not changed since the shortcut was saved.

The rules of the prototype chain are covered in Prototype chain, Object.create, Class inheritance, and Native prototypes. This lesson is about the engine side. The lesson before this one, Functions & closures inside the engine, showed how the engine stores functions. Here you see how it finds methods that live on a prototype.

First, the rules the engine must keep. The code below uses two tools:

  • Object.create(proto) makes a new, empty object whose prototype is proto.
  • Object.setPrototypeOf(obj, other) gives an existing object obj a new prototype, other.
What JavaScript promises when a prototype changesPop out in the code editor (opens in a new tab)JavaScript
const proto = {  label: "from prototype",  method() {    return "old method";  },};const child = Object.create(proto); console.log(child.label);child.label = "own label";console.log(child.label);console.log(proto.label);proto.method = function method() {  return "new method";};console.log(child.method());Object.setPrototypeOf(child, { label: "new prototype" });delete child.label;console.log(child.label);
  • Line 7 makes child, with proto as its prototype.
  • Line 9 reads child.label. child has no label of its own, so JavaScript finds it on proto and prints from prototype.
  • Line 10 gives child its own label. An object's own property hides a prototype property with the same name. This is called shadowing.
  • Line 11 prints own label. Line 12 prints proto.label, which is still from prototype.
  • Lines 13 to 15 put a new method on proto. Line 16 calls it through child and prints new method.
  • Line 17 gives child a new prototype. Line 18 deletes the own label. Line 19 prints new prototype, read from the new prototype.

Any shortcut the engine saves must still print these same five lines.

Real-life analogyA family recipe book with a bookmark

You want a recipe. You check your own recipe card first. If it is not there, you open the family book. The first time, you search page by page. Then you leave a bookmark on the right page, with a sticker that says "still correct".

Next time, you see the sticker and open the book at the bookmark. If someone edits the book, they peel the sticker off. Then you search page by page again, and put down a new bookmark.

In real life: You check your own recipe card first
In JavaScript: JavaScript looks on the object first
In real life: Shared recipes are in the family book
In JavaScript: Shared methods are on the prototype
In real life: A bookmark takes you straight to the right page
In JavaScript: A saved shortcut goes straight to the prototype
In real life: A sticker on the bookmark says "still correct"
In JavaScript: A validity cell says the chain has not changed
In real life: Someone edits the book and peels off the sticker
In JavaScript: A change to the prototype marks the cell invalid

Prototype maps

The engine keeps a hidden note for every object. The note lists which properties the object has and where each one is stored. V8 (the engine in Chrome and Node) calls this note a map. SpiderMonkey (the engine in Firefox) calls it a shape. Both words mean the same thing here. Your code never sees a map.

Many objects can share one map when they have the same properties, added in the same order. The hidden classes lesson explains maps in depth. Here you need one new idea: an object that other objects use as their prototype gets extra notes, because many objects now depend on it.

The table below lists the engine words used in this lesson. Read each row from left to right: the word, what it means, and why it matters for prototypes.

Engine words for prototypes, in plain words
Engine wordWhat it meansWhy prototypes need it
Map (shape in SpiderMonkey)The engine's hidden note about an object: which properties it has, and where each one is stored.Many objects can share one map when they get the same properties in the same order.
Prototype mapThe map of an object that other objects use as their prototype.V8 adds extra notes to it, such as prototype info and a validity cell, because other objects depend on it.
Prototype link in a mapAn object's map also records which prototype the object links to.One map check proves the object still has no own copy of the property and still has the same prototype. Object.setPrototypeOf(obj, other) gives obj a new map.
Validity cellA tiny flag, valid or invalid, that saved shortcuts to a prototype check.When a prototype on the chain changes, its cell turns invalid, and old shortcuts fail.

Mathias Bynens and Benedikt Meurer, who worked on V8, describe one useful trick. An object's map also records which prototype the object links to. So one check of the map answers two questions at once:

  • Does this object still lack its own copy of the property?
  • Does this object still link to the same prototype?

You can see the extra notes in Node with special V8 commands. Commands that start with %, like %DebugPrint, only work when Node runs with the --allow-natives-syntax flag. They are not normal JavaScript, so this code does not run in the browser.

Node only: V8 adds prototype notes to an object once it is used as a prototypeJavaScript
const proto = {  kind: "rect",  getArea() {    return 12;  },};console.log(  `Node ${process.versions.node} (V8 ${process.versions.v8.split(".").slice(0, 2).join(".")})`,);console.log("before fast properties", %HasFastProperties(proto));const rect = Object.create(proto);console.log("after used as prototype", %HasFastProperties(proto));%DebugPrint(proto);void rect;
  • Lines 1 to 6 make a normal object, proto.
  • Lines 7 to 9 print the Node and V8 version.
  • Line 10 asks V8 whether proto uses its normal, fast way of storing properties. It prints true.
  • Line 11 makes rect with proto as its prototype. Line 12 asks again and now prints false.
  • Line 13 prints everything V8 knows about proto.
What the test checked

The lesson test runs this code in Node 22 with V8 12.4. It only checks facts that stay the same from run to run. The printout contains prototype_map, prototype info, and prototype_validity cell. In this version, %HasFastProperties(proto) is true before the object becomes a prototype and false after. That does not mean lookups on prototypes are slow. It only means V8 now stores and tracks this object in a different way.

You don't need to remember the exact printout. The main point: a prototype is still a normal JavaScript object. But once other objects depend on it, the engine marks it and keeps an eye on it.

Caching inherited property lookups

A method call does two jobs. Take rect.getArea():

  1. JavaScript finds getArea. This is a normal property read.
  2. JavaScript calls that function with this set to rect.

The first job can be slow if the engine walks the whole chain on every call. Step through it below.

Step through finding a method on the prototype
Step 0 of 6Ready
Your turn: follow the blue line

Follow one method call. First JavaScript finds the method on the prototype, then it runs it with the numbers from rect.

Running in
  1. script
Next: line 1
  getArea() {    return this.width * this.height;  },};const rect = { width: 3, height: 4 };Object.setPrototypeOf(rect, rectPrototype); console.log(rect.getArea());
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
  • Line 6 makes rect with its own width and height.
  • Line 7 links rect to rectPrototype.
  • Line 9 asks for getArea. rect does not have it, so JavaScript finds it on the prototype.
  • Line 3 runs inside the method. It reads width and height from rect, because this is rect. The method is shared, but the numbers belong to each object.
Reading rect.getArea. The rect cart holds width 3 and height 4 but no getArea. An arrow goes on to the prototype cart, which holds the getArea function.rect.getArea()width: 3height: 4rectnot heregetArea()prototype1. look here first2. found here
JavaScript looks for getArea on rect first. It is not there, so JavaScript follows the link to the prototype and finds it there.

To skip the walk next time, the engine saves a shortcut at that line of code. A saved shortcut like this is called a cache. The table below shows what happens on each read. Each row is one moment: what JavaScript does, and what the shortcut saves or does.

What happens to the saved shortcut on each read
WhenWhat JavaScript doesWhat the shortcut saves or does
The first readLooks on the object, then walks up the prototypes, following the normal rules.Saves a shortcut, if this kind of read can be saved.
A later read, nothing changedGives the same answer as a full walk.Checks the object's map and the validity cell, then reads the prototype's slot straight away. It never saves the old value.
A property is added to or deleted from the prototypeFinds the property using the changed prototype.The prototype gets a new map and the old cell turns invalid. The next read walks again and saves a fresh shortcut.
The object gets a new prototypeLooks on the new prototype.The object gets a new map, so the map check fails, even if the old cell is still valid.

The inline caches lesson showed shortcuts for an object's own properties. A shortcut for an inherited property saves more:

  • The map of the object you read from, like rect.
  • Which prototype has the property.
  • The slot: the place in that prototype where the value is stored.
  • A validity cell: a small flag that says the chain has not changed. The next section explains it.
The saved shortcut for rect.getArea. Check 1: is rect's map the same? Check 2: is the cell still valid? If both say yes, go straight to getArea on the prototype.the next time rect.getArea is readsame map?yescell valid?yesgetArea()prototypecheck 1check 2read it here
The shortcut does not save the method itself. It saves two checks and the place to read from. If both checks pass, the engine skips the walk and reads getArea straight from the prototype.

Validity cells

A validity cell is a tiny flag inside the engine. It says either "valid" or "invalid". Many saved shortcuts can share one cell. Here is how V8 uses it:

  1. When a shortcut is saved, it keeps a link to the current cell.
  2. If a prototype on the chain changes, the engine marks that cell invalid.
  3. The next time a shortcut runs, it sees the invalid cell. It walks the chain again and saves a fresh shortcut.

The code below is a small model of this, written in plain JavaScript. It is not the real engine. Step through it to watch one shortcut being saved, used, and refused.

Step through a saved shortcut and its validity cell
Step 0 of 12Ready
Your turn: follow the blue line

Watch one saved shortcut: the first read saves it, the second uses it, a change marks its cell invalid, and the third read saves it again.

Running in
  1. script
Next: line 1
const cache = { receiverMap: null, holder: null, offset: null, cell: null };const rectProto = { slots: { getArea() { return 12; } } };const rect = { map: "RectMap#1", prototype: rectProto }; function loadGetArea(receiver) {  if (cache.receiverMap === receiver.map && cache.cell?.valid) {    return cache.holder.slots[cache.offset];  }  const holder = receiver.prototype;  cache.receiverMap = receiver.map;  cache.holder = holder;  cache.offset = "getArea";  cache.cell = validityCell;  return holder.slots.getArea;} console.log(loadGetArea(rect)());console.log(loadGetArea(rect)());validityCell.valid = false;validityCell = { valid: true };rectProto.slots.getArea = () => 20;console.log(loadGetArea(rect)());
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
  • Line 18 is the first read. Nothing is saved yet, so the model walks to the prototype and saves a shortcut.
  • Line 19 is the second read. The map matches and the cell is valid, so the model uses the shortcut.
  • Line 20 marks the old cell invalid. Line 22 replaces the method with one that returns 20.
  • Line 23 is the third read. The old cell is invalid, so the model walks again, saves a fresh shortcut, and prints 20.
Left: on line 19 the cell is valid, so the shortcut is used and the call gives 12. Right: on line 23 the old cell is invalid, so the engine walks the chain again and the call gives 20.line 19cellvalid12use the shortcutline 23old cellinvalid20walk the chain again
On line 19 the cell still says valid, so the shortcut runs and gives 12. Line 20 marks the cell invalid, so on line 23 the engine walks the chain again and finds the new method, which gives 20.

The shortcut never saves the value 12. It saves a safe way to reach the slot. So after the change, line 23 prints 20, as JavaScript requires. The price of the change is that old shortcuts stop working and must be saved again.

Valid means "the chain has not changed"

A valid cell only means one thing: the facts about the chain that this shortcut relied on are still true. It does not mean the method is fast, or that it will never change. Fast machine code for a call can also depend on which exact function it calls. The engine tracks that separately.

V8's article on prototype speed-ups warns that changing Object.prototype is the widest change of all. Almost every object has Object.prototype at the end of its chain. So changing it can mark many cells invalid at once, including the chains of page elements in a browser. That is why adding to global prototypes after an app has started running is expensive.

Shape teleporting in SpiderMonkey

SpiderMonkey is Firefox's engine. It uses the word shape where V8 says map. It has its own trick for long chains, called shape teleporting. The goal: don't check every object in the middle of the chain on every read.

The block below is a sketch, not real code. It uses three made-up steps:

  • GuardShape(x) checks that object x still has the same shape.
  • LoadSlot(x, "y") reads the value of y from its slot in x.
  • holderPrototype is the prototype that has y. middlePrototype sits between it and obj.
Two ways to check the chain before reading obj.yText
Simple shortcut for obj.y (checks every object):  GuardShape(obj)  GuardShape(middlePrototype)  GuardShape(holderPrototype)  LoadSlot(holderPrototype, "y") SpiderMonkey shape teleporting (checks two):  GuardShape(obj)  GuardShape(holderPrototype)  LoadSlot(holderPrototype, "y")  If middlePrototype gets its own "y":    change shapes, so the old checks fail
  • Lines 1 to 5: a simple shortcut checks all three objects, then reads y.
  • Lines 7 to 10: shape teleporting checks only obj and holderPrototype, then reads y.
  • Lines 11 and 12: the rule that keeps this safe. If middlePrototype gets its own y, SpiderMonkey changes the shapes, so the old checks fail.
Top row, a simple cache: it checks obj, the middle prototype, and the prototype that has y. Bottom row, shape teleporting: it checks obj and the prototype that has y, and skips the middle one.simpleobjmiddlehas ycheckcheckcheckteleportobjmiddlehas ycheckskippedcheck
Both rows read obj.y from the same chain. Shape teleporting skips the check on the middle object. SpiderMonkey keeps this safe by changing shapes if the middle object ever gets its own y.

Matthew Gaudet's post about SpiderMonkey explains why the rule is needed. Skipping the middle check is only safe if any change in the middle also changes a shape that is checked. SpiderMonkey makes sure of that. It changes shapes when a middle prototype starts shadowing the property, and when a prototype link changes.

Real-life analogyA note that says which classroom has the worksheet

A student needs a worksheet. A note on the door says which classroom hands it out, so the student goes straight there. The student does not check every room on the way.

Then a nearer classroom starts handing out the same worksheet. The school must take the old note away at once. Otherwise the student walks past the nearer room to the wrong one.

In real life: A student wants a worksheet
In JavaScript: Code reads a property
In real life: A note names the classroom that has it
In JavaScript: The shortcut knows which prototype has the property
In real life: A nearer classroom starts handing it out
In JavaScript: A middle prototype gets its own copy of the property
In real life: The school takes the old note away
In JavaScript: SpiderMonkey changes shapes, so the old shortcut fails

Shape teleporting is not a new JavaScript feature. The rules still say a lookup walks the chain. Shape teleporting only lets SpiderMonkey get the same answer with fewer checks.

Why changing a prototype is slow

You may change a prototype with Object.setPrototypeOf or by assigning to __proto__. Both are allowed. But both break facts that saved shortcuts and fast code rely on. MDN warns that changing an object's prototype is slow in modern engines. The cost is not only in that one line. Other code that was made fast for the old chain can slow down too.

When a function runs many times, V8 turns it into fast machine code. This is called optimizing. If a fact that the fast code relied on stops being true, V8 throws that code away and goes back to slower code. This is called deoptimizing.

Node only: V8 throws away fast code after a prototype method is replacedJavaScript
const proto = {  getArea() {    return 12;  },};const rect = Object.create(proto); function area(object) {  return object.getArea();} %PrepareFunctionForOptimization(area);for (let i = 0; i < 10000; i += 1) area(rect);%OptimizeFunctionOnNextCall(area);console.log("before", area(rect));proto.getArea = function getArea() {  return 20;};console.log("after", area(rect));
  • Line 8 defines area, which calls object.getArea().
  • Line 12 tells V8 to get ready to optimize area. Line 13 runs it 10,000 times. Line 14 tells V8 to optimize it on the next call.
  • Line 15 prints before 12, using the fast code.
  • Line 16 replaces getArea on the prototype. Line 19 prints after 20.
What the test checked

The lesson test runs this with --allow-natives-syntax --trace-opt --trace-deopt --no-concurrent-recompilation. These flags make V8 print when it optimizes and deoptimizes code. The test checks that the output changes from before 12 to after 20. It also checks that V8 prints a line that starts with "marking dependent code" and ends with "for deoptimization, reason: code dependencies". That line appears after the method is replaced.

Replacing a method is not the same as adding a property. The method still sits in the same slot, so a simple shortcut to the slot can still work. But the fast code may have copied the old function into itself, or checked for it. So V8 tracks that separately, and the next call still gives the right answer.

Experiment: change the prototype chain

This playground is a small model of the shortcut. Each change has one of three results:

  • The validity cell turns invalid, so the shortcut is refused.
  • The object's map changes, so the map check fails.
  • The shortcut can still be used.

Press Read area twice first, so there is a shortcut to reuse. Then try each change and read again.

Playground: change the prototype chain
The model: one line of code that reads rect.getAreaJavaScript
const site = createInheritedLoadSite("getArea");const rect = makeRect(3, 4); site.read(rect);                 // first read: walk, save a shortcutsite.read(rect);                 // uses the shortcutrect.width = 5;                  // shortcut still worksrect.__proto__.perimeter = 18;   // new prototype map, cell turns invalidsite.read(rect);                 // shortcut refused: walk, save again
Saved shortcut0 used · 0 not used
0 times used0 times not used0 changes that broke it0 fast code thrown away
map of rectRectMap#2
map of prototypeProtoMap#1
validity cellcell#1
cell is validtrue
saved map of rectempty
saved map of prototypeempty
saved cellempty
prototype propertiesgetArea

No reads yet. Press Read area to save the first shortcut.

Step 0 of 6ready

Press Read area to read rect.getArea. Then change the object or its prototype, and read again.

This is a small model, not your browser's real engine. It shows the map check, the validity cell, and fast code that relies on one function, as described in the lesson.
What breaks the saved shortcut?
  • Add perimeter to Rect.prototype after the shortcut is saved.
  • Delete a helper from Object.prototype after using it.
  • Call Object.setPrototypeOf(rect, otherMethods).
  • Assign rect.getArea = function () { return 99; }.
  • Assign rect.width = 5, while getArea stays on the prototype.
  • Put a new function in Rect.prototype.getArea.
Try it yourself
0 of 6 correct

Sort each change by what happens to the shortcut in this lesson's model.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Practical use

Most developers never need to think about prototype maps. The useful habits are simple:

  • Give each object the right prototype when you create it.
  • Don't change prototypes in code that runs very often.
  • Don't add to built-in prototypes after the app has started.
  • Measure before you rewrite readable code for speed.
Give each object its prototype when you create itPop out in the code editor (opens in a new tab)JavaScript
const rectMethods = {  getArea() {    return this.width * this.height;  },}; const card = Object.create(rectMethods);card.width = 3;card.height = 4;console.log(card.getArea()); const nextCard = Object.create(rectMethods);nextCard.width = 5;nextCard.height = 2;console.log(nextCard.getArea());

Line 1 makes one object that holds the shared method. Lines 7 and 12 use Object.create to set the prototype at the moment each object is made. Lines 10 and 15 print 12 and 10. This is different from making an object, using it many times, and then changing its prototype. If a library must add to a prototype, doing it before the busy code starts is less harmful than doing it in the middle.

  • Make objects with Object.create(proto), a class, or a constructor function. Don't change their prototype later.
  • Don't add to Object.prototype or other built-in prototypes in code that runs often.
  • Changing an object's own data, like rect.width, is fine. The method's result changes, but the shortcut to the method still works.
  • Use a profiler (a tool that measures where time goes) before you change your design for prototype speed.

The next lesson, The heap & pointer compression, moves from prototype notes to how values and objects are laid out in memory.

Common misconceptions

  • "The engine saves inherited values." It saves a checked way to reach the slot. The value in the slot can still change.
  • "Changing a prototype only costs that one line." It can also throw away fast code that relied on the old chain.
  • "A prototype map is a JavaScript feature." Maps, shapes, and validity cells belong to the engine. The language does not mention them.
  • "Shape teleporting breaks the lookup rules." It skips checks only when shape changes keep the answer correct.
  • "All prototype changes cost the same." Adding a prototype property, replacing a method, changing an object's data, and setting a new prototype each break different checks.

The table below compares ideas that look alike. Each row says what the idea means, and what it does not mean.

Ideas that are easy to mix up
IdeaWhat it meansWhat it does not mean
The prototype chain rulesThe JavaScript rules say a read checks the object's own properties, then its prototypes.The rules do not ask for maps, validity cells, saved shortcuts, or shape teleporting.
A saved shortcut to a prototypeA checked way to reach the place where the property was found.A saved copy of the property's value.
Replacing a methodJavaScript must call the new function on the very next read.The same as adding or deleting a property. The slot stays where it is, but fast code that relied on the old function is thrown away.
Shape teleportingSpiderMonkey skips checks on middle prototypes, and changes shapes so this stays correct.Breaking JavaScript's lookup rules.

Practice exercises

Exercise 1 · Warm-upPredict what shadowing prints

Type the three values the code prints.

Starter codePop out in the code editor (opens in a new tab)JavaScript
const proto = { price: 100 };
const item = Object.create(proto);
console.log(item.price);
item.price = 120;
console.log(item.price);
console.log(proto.price);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upReplace a prototype method

    What does item.tag() print after the prototype method is replaced?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const proto = { tag() { return "old"; } };
    const item = Object.create(proto);
    proto.tag = function tag() { return "new"; };
    console.log(item.tag());

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeName the second check

      A saved shortcut to an inherited property checks the object's map. What else does V8 check?

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFind the slow line

        The tests also run a small Object.setPrototypeOf program: item starts with a prototype whose label is "old", then gets a new prototype whose label is "new". What does item.label print after the switch?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        // Problem: this line runs after the app has been busy for a while.
        Object.setPrototypeOf(card, premiumCardMethods);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeUse it in a real app

          Your app changes a prototype every time the page scrolls. Name one safer habit from the Practical use section.

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeName the SpiderMonkey trick

            Which SpiderMonkey trick lets a shortcut check only the first object and the prototype that has the property?

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              For each question, first work out what JavaScript prints. Then name the engine check that keeps the shortcut correct.

              Prototype internals quiz · 7 questionsScore: first tries count
              1. Question 1 of 7In V8, what does a saved shortcut to an inherited property check before it reads?

                Choose an answer to see the explanation.

              2. Question 2 of 7What does this shadowing snippet print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                const proto = { price: 100 };
                const item = Object.create(proto);
                console.log(item.price);
                item.price = 120;
                console.log(item.price);
                console.log(proto.price);

                Choose an answer to see the explanation.

              3. Question 3 of 7Why does Object.setPrototypeOf slow down fast code?

                Choose an answer to see the explanation.

              4. Question 4 of 7What does this method replacement print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                const proto = { tag() { return "old"; } };
                const item = Object.create(proto);
                proto.tag = function tag() { return "new"; };
                console.log(item.tag());

                Choose an answer to see the explanation.

              5. Question 5 of 7What does SpiderMonkey's shape teleporting try to avoid?

                Choose an answer to see the explanation.

              6. Question 6 of 7Which change leaves the shortcut to getArea working, but still changes what getArea returns?

                Choose an answer to see the explanation.

              7. Question 7 of 7What did the Node and V8 printout in this lesson show?

                Choose an answer to see the explanation.

              Key takeaways

              • Every method call starts with a property read. Shortcuts make that read faster. They never change this or the shadowing rules.
              • In V8, an object used as a prototype gets extra notes, such as prototype info and a validity cell.
              • A saved shortcut checks the object's map and the validity cell. Then it reads straight from the prototype's slot.
              • SpiderMonkey's shape teleporting skips checks on middle prototypes. It stays correct because changes in the middle change a shape that is checked.
              • Changing prototypes, or adding to built-in prototypes, after code has run many times can throw away a lot of fast code. Set the prototype when you create the object, and measure first.

              In one line: the engine trusts its saved shortcuts to prototypes only while their checks still pass.

              Next: The heap & pointer compression shows where these objects, maps, and values live in memory.

              CompleteFrontend Clear concepts. Working examples.