Let's explain what a closure is by writing a JavaScript interpreter in JavaScript.
The goal of this project is not to make a spec-compliant or blazing-fast interpreter. The goal, however, is to interpret a tiny subset of JavaScript features in super-easy-to-read™ code.
- Numbers, Booleans,
null
, andundefined
12 // Numeric Literal
true // Boolean Literal
null // Null Literal
undefined // Do you know that `undefined` is actually an identifier?
- Variable, a.k.a. Identifier
foo
- Binary Operators
+, -, *, /, ==, ===, !=, !==, <, <=, >, >=
- Unary Operators
!, -
- Conditional Expression, a.k.a. the ternary operator
test ? consequent : alternate
- Arrow Function Expression
- Notice that we didn't implement the traditional
function
syntax. Arrow functions FTW!
(x) => x + 1
(x) => {
const y = x + 100;
return y * y;
}
- Call Expression
foo(1, 2, 3)
- Variable Declaration Statement
- Notice that we only support
const
for now and there's NO mutation (assignment) in our language.- That means we can initialize stuff once and only once
- And of course
const foo
is not valid JavaScript
- If you are familiar with Scheme/OCaml, then
const LHS = RHS
behaves just like aletrec
.
const foo = 12;
const fact = (x) => x < 2 ? 1 : x * fact(x - 1);