跪拜 Guibai
← All articles
Front-End

Storage and `this` in JavaScript: The Two Interview Topics That Trip Up Every Front-End Candidate

By 两只羊ovo ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Misunderstanding the storage hierarchy leads to architectures that either pound the database unnecessarily or leak sensitive data into browser-accessible stores. Getting `this` wrong produces bugs that survive code review because the function looks correct where it's defined — the error only surfaces at a different call site.

Summary

Server-side storage follows a tiered chain: MySQL holds the source of truth, Redis sits in front as a hot cache, and the browser chips in with its own cache and localStorage for offline persistence. The whole point is to avoid hammering the database on every read. On the client, localStorage acts as a tiny, same-origin key-value store limited to about 5MB and strings only — forget to JSON-serialize an object and you get `[object Object]`.

`this` in JavaScript is determined entirely by the call site. A regular function call points to `window` (or `undefined` in strict mode); a method call points to the object before the dot; a constructor call points to the new instance; an event handler points to the element that fired the event; and `call`/`apply`/`bind` let you override all of that. The most common pitfall is reference assignment: pulling a method off an object and calling it bare loses the original binding.

`var` declarations leak onto `window`, which creates a subtle trap inside `setTimeout` callbacks — a regular function there finds `window.name` instead of the object's property. Arrow functions fix this by inheriting `this` from the enclosing lexical scope, and they ignore any attempt to rebind with `call` or `apply`.

Takeaways
MySQL, Redis, cloud storage, browser cache, and localStorage form a five-layer caching chain; the typical read path hits Redis first and falls back to MySQL only on a cache miss.
localStorage is a synchronous, same-origin key-value store capped at roughly 5MB; it stores only strings, so objects must go through `JSON.stringify` and `JSON.parse`.
Default `<form>` submission triggers a full page refresh; `e.preventDefault()` inside a submit handler stops that and lets `fetch` or `ajax` take over.
`this` is bound at call time: regular calls get `window` (or `undefined` in strict mode), method calls get the owning object, `new` gets a fresh instance, and event handlers get the target element.
Assigning a method to a variable strips its `this` binding — `const fn = obj.say; fn();` runs with `this` as `window`, not `obj`.
`call` and `apply` invoke the function immediately with a specified `this`; `bind` returns a new function with `this` locked in, which is ideal for event listeners and delayed callbacks.
`var` attaches to `window`, so a `setTimeout` callback using a regular function can accidentally read a global variable instead of an object property.
Arrow functions have no own `this` — they capture it from the enclosing scope and ignore `call`, `apply`, and `bind`.
Conclusions

The storage hierarchy mirrors backend patterns that have been standard for a decade, but front-end developers often encounter them only as interview trivia rather than as a design tool they reach for daily.

Reference assignment breaking `this` is not a quirk — it follows directly from the rule that `this` is call-site determined, yet it remains the single most common source of binding bugs in JavaScript codebases.

`var` polluting `window` is a legacy behavior that still bites in codebases mixing old scripts with modern modules; the interaction with `setTimeout` is a particularly nasty edge case because the bug is silent until a global variable happens to shadow an object property.

Concepts & terms
Reference assignment (losing `this`)
When a method is extracted from an object and assigned to a standalone variable, the function reference no longer carries the object binding. Calling the variable invokes the function as a plain call, so `this` defaults to the global object (or `undefined` in strict mode) rather than the original object.
Arrow function `this` binding
Arrow functions do not get their own `this` value. They capture `this` from the enclosing lexical scope at the time they are defined, and this binding cannot be overridden with `call`, `apply`, or `bind`.
`var` polluting `window`
Variables declared with `var` in the global scope become properties of the global `window` object. This means a `setTimeout` callback using a regular function can inadvertently read a `var`-declared global instead of an object property, because the callback's `this` defaults to `window`.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗