The first chapter of You Don’t Know JS Yet opens with a bold admission: no one fully knows JavaScript. But that’s not a flaw — it’s an invitation. Knowing JS is not a destination, but a direction. This chapter sets the tone for a journey of curiosity, patience, and depth.
One of the most persistent misconceptions in programming is that JavaScript is somehow a derivative of Java. It’s not. The name “JavaScript” was a marketing decision made during the early days of the web to appeal to Java developers. Brendan Eich originally called the language Mocha, and it was briefly known as LiveScript before being renamed.
Despite superficial syntactic similarities — like using {} for code blocks and ; for statement endings — JS and Java are fundamentally different. As Jeremy Keith famously put it: “Java is to JavaScript as ham is to hamster.”
To understand JavaScript’s evolution, it’s important to know that the language is formally standardized as ECMAScript by the TC39 committee under ECMA International. Since 2016, the standard has been versioned by year — for example, ES2019 — and the JavaScript engines in browsers and Node.js implement these specifications.
Terms like “JS6” or “ES8” are discouraged, as they often lead to confusion. Instead, use “JS” or the official ES20xx naming convention.
The official governance of JavaScript lies with TC39, a technical committee under ECMA International. TC39 includes 50–100 members from web-focused companies like Mozilla, Google, Apple, and Samsung. While members volunteer their time, many are employed by these companies and compensated for their contributions.
TC39 meets every two months to review proposals and vote on changes. Proposals move through a five-stage process (starting at Stage 0) before reaching Stage 4, at which point they’re eligible for inclusion in the next ECMAScript release.
Contrary to outdated myths, there is only one official version of JavaScript today — the ECMAScript standard maintained by TC39 and ECMA. In the early 2000s, Microsoft’s JScript created fragmentation, but those days are long gone. All major JS engines now follow the same specification.
Although JS runs in many environments (browsers, Node.js, devices, robots), the web remains its dominant context. Sometimes, browser engines diverge from the specification to preserve compatibility with legacy web content. In such cases, TC39 may adjust the spec to match reality — as seen with the renaming of contains() to includes() and the infamous smooshgate that led to flat().
To accommodate browser-specific behaviors, ECMAScript includes Appendix B, which lists features allowed only in web JS environments. These include:
escape() and unescape() functionsanchor() and blink()compile() method in RegExpSome of these features trigger early errors in strict mode. To ensure future compatibility, developers should avoid relying on them.
alert("Hello, JS!") follows JS syntax, but alert itself is not defined in the JS spec. It’s a web API provided by the browser environment. The same applies to console.log(), fetch(), and many other familiar functions. They look like JS, behave like JS, but are technically guests in the JS runtime.
Most complaints about JS inconsistency stem from differences in these environment APIs, not the language itself.
Using the browser console or Node.js REPL may feel like writing pure JS, but these tools are designed for developer convenience. They prioritize DX (Developer Experience) over strict spec compliance. Features like auto-complete and variable previews are helpful, but they don’t always reflect true JS behavior.
Since console behavior varies across browsers and changes frequently, it’s best not to treat it as a strict JS environment.
The browser console is a JS-friendly environment, but it’s not a strict JS engine. It’s designed for quick experimentation, not for faithfully replicating how a .js file is parsed and executed. As such, several quirks arise:
var and function declarations may create global variables and mirror window properties, but behavior can vary.let/const Declarations: Re-declaring these in the top-level console scope can throw errors, unlike var."use strict"; on one line doesn’t necessarily enable strict mode for the entire session.this may refer to the global object, but the expected globals may not behave consistently.In short, don’t treat console behavior as canonical JS. For that, consult the ECMAScript specification.
JavaScript is a multi-paradigm language, meaning it supports multiple styles of programming:
JS lets you mix and match these paradigms freely, even within a single program. This flexibility is rare and powerful, allowing developers to choose the best approach for each problem.
One of JS’s core principles is backwards compatibility. Once code is accepted as valid JS, it should continue to work in future versions. TC39’s motto is: “We don’t break the web.”
This commitment ensures that code written in 1995 still runs today. It makes JS a safe long-term investment, but also creates challenges: once a feature is added, it’s effectively permanent — even if flawed.
Occasional backwards-incompatible changes do happen, but only after careful analysis and consensus among browser vendors. These changes are rare and usually affect obscure edge cases.
Unlike HTML and CSS, JS is not forwards-compatible. New JS features can break in older engines. This is because programming languages are imperative — skipping unknown statements would lead to unpredictable behavior.
In contrast, HTML and CSS are declarative. Browsers can safely ignore unknown tags or styles without affecting the rest of the document. That’s why a 2019 CSS feature won’t break a 2010 browser — it’ll just be ignored.
JavaScript is not forward-compatible. That means using newer features like ES2019 in older engines may cause errors. To solve this, tools like Babel are used to transpile modern code into older syntax. For example, let can be converted to var with unique names to preserve block scoping.
Transpiling allows developers to write clean, modern code while ensuring compatibility with legacy browsers. The target environment evolves as older browsers are phased out.
For features missing in older engines (like Promise.prototype.finally), developers use polyfills — fallback implementations that mimic native behavior.
Example:
if (!Promise.prototype.finally) {
Promise.prototype.finally = function (callback) {
return this.then(
value => Promise.resolve(callback()).then(() => value),
reason => Promise.resolve(callback()).then(() => { throw reason; })
);
};
}Tools like Babel often include polyfills automatically, but manual inclusion may be needed in some cases.
Though JS is often called a scripting language, it is actually compiled. JS engines parse code into an AST (Abstract Syntax Tree), then compile it into bytecode, and optimize it using JIT (Just-In-Time) compilation.
This process catches early errors (like duplicate parameters) before execution, aligning JS more with compiled languages than interpreted ones.
To improve performance, JS evolved through ASM.js — a subset with type hints — and then WASM, a binary format that skips parsing and compiles ahead of time.
WASM allows languages like C and Go to run in JS engines. It complements JS rather than replacing it. Tools like AssemblyScript help bridge JS to WASM, but JS’s dynamic typing makes it less ideal for WASM directly.
Introduced in ES5, strict mode enforces better coding practices and optimization. It’s activated by "use strict"; at the top of a file or function. In strict mode, this in non-method functions becomes undefined, helping avoid accidental global bindings.
A stray semicolon before the directive can silently disable strict mode. File-level strict mode is preferred over function-level for consistency.
JavaScript supports multiple programming styles:
JS lets developers mix these styles freely, choosing the best approach for each problem.
JS is backward-compatible — code written in 1995 should still run today. TC39’s motto is: “We don’t break the web.” This makes JS a safe long-term investment, but also means features are effectively permanent once added.
JS is not forward-compatible: using new features in old engines causes errors. Unlike HTML/CSS, which are declarative and can ignore unknown tags or styles, JS is imperative — skipping unknown statements would break logic.
JavaScript is a dynamic, compiled, multi-paradigm language that runs across diverse environments. With tools like transpilers and polyfills, developers can write modern code while maintaining compatibility. WASM enhances performance, strict mode enforces discipline, and backward compatibility ensures JS remains a stable foundation for the web — even as it evolves.