~9 min read • Updated Oct 14, 2025
Introduction: You Don’t Know JS — Yet
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.
JavaScript Is Not Java
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.”
JS, ECMAScript, and the Standards
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.
TC39 and the ECMAScript Standard
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.
One JavaScript, One Standard
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.
The Web Rules JavaScript
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().
Appendix B – Web-Specific Features
To accommodate browser-specific behaviors, ECMAScript includes Appendix B, which lists features allowed only in web JS environments. These include:
- Octal literals with 0 prefix
escape()andunescape()functions- Legacy string methods like
anchor()andblink() compile()method in RegExp
Some of these features trigger early errors in strict mode. To ensure future compatibility, developers should avoid relying on them.
Is alert() Part of JavaScript?
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.
The Console Is Not Pure JS
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.
Developer Console: Not Quite Spec JS
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:
- Global Scope:
varandfunctiondeclarations may create global variables and mirrorwindowproperties, but behavior can vary. - Multiple
let/constDeclarations: Re-declaring these in the top-level console scope can throw errors, unlikevar. - Strict Mode: Entering
"use strict";on one line doesn’t necessarily enable strict mode for the entire session. - Default Binding: In non-strict mode,
thismay refer to the global object, but the expected globals may not behave consistently. - Hoisting: Across multiple line entries, hoisting may not behave as it would in a single .js file.
In short, don’t treat console behavior as canonical JS. For that, consult the ECMAScript specification.
JavaScript’s Many Paradigms
JavaScript is a multi-paradigm language, meaning it supports multiple styles of programming:
- Procedural: Code flows top-down through procedures and operations.
- Object-Oriented: Logic and data are grouped into classes and objects.
- Functional: Code is composed of pure functions and transformations.
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.
Backwards vs. Forwards Compatibility
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.
Why JS Isn’t Forwards-Compatible
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.
Jumping the Gaps: Transpiling and Compatibility
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.
Filling the Gaps: Polyfills for Missing APIs
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.
Interpreted or Compiled?
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.
WebAssembly: A Performance Companion
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.
Strict Mode
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 as a Multi-Paradigm Language
JavaScript supports multiple programming styles:
- Procedural: Linear, step-by-step execution
- Object-Oriented: Classes and objects encapsulate logic and data
- Functional: Pure functions and composition
JS lets developers mix these styles freely, choosing the best approach for each problem.
Backward vs. Forward Compatibility
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.
Conclusion
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.
Written & researched by Dr. Shahin Siami