What Is JavaScript Made Of?
Getting a closure on JavaScript.
What Is JavaScript Made Of?
December 20, 2019
During my first few years of using JavaScript, I felt like a fraud. Even though I could build websites with frameworks, something was missing. I dreaded JavaScript job interviews because I didn’t have a solid grasp on fundamentals.
Over the years, I’ve formed a mental model of JavaScript that gave me confidence. Here, I’m sharing a very compressed version of it. It’s structured like a glossary, with each topic getting a few sentences.
As you read through this post, try to mentally keep score about how confident you feel about each topic. I won’t judge you if quite a few of them are a miss! At the end of this post, there is something that might help in that case.
Value: The concept of a value is a bit abstract. It’s a “thing”. A value to JavaScript is what a number is to math, or what a point is to geometry. When your program runs, its world is full of values. Numbers like 1, 2, and 420 are values, but so are some other things, like this sentence: "Cows go moo". Not everything is a value though. A number is a value, but an if statement is not. We’ll look at a few different kinds of values below.
- Type of Value: There are a few different “types” of values. For example, numbers like
420, strings like"Cows go moo", objects, and a few other types. You can learn a type of some value by puttingtypeofbefore it. For example,console.log(typeof 2)prints"number".
- Primitive Values: Some value types are “primitive”. They include numbers, strings, and a few other types. One peculiar thing about primitive values is that you can’t create more of them, or change them in any way. For example, every time you write
2, you get the same value2. You can’t “create” another2in your program, or make the2value “become”3. This is also true for strings.
nullandundefined: These are two special values. They’re special because there’s a lot of things you can’t do with them — they often cause errors. Usually,nullrepresents that some value is missing intentionally, andundefinedrepresents that a value is missing unintentionally. However, when to use either is left to the programmer. They exist because sometimes it’s better for an operation to fail than to proceed with a missing value.
Equality: Like “value”, equality is a fundamental concept in JavaScript. We say two values are equal when they’re… actually, I’d never say that. If two values are equal, it means they are the same value. Not two different values, but one! For example, "Cows go moo" === "Cows go moo" and 2 === 2 because 2 is 2. Note we use three equal signs to represent this concept of equality in JavaScript.
- Strict Equality: Same as above.
- Referential Equality: Same as above.
- Loose Equality: Oof, this one is different! Loose equality is when we use two equal signs (
==). Things may be considered loosely equal even if they refer to different values that look similar (such as2and"2"). It was added to JavaScript early on for convenience and has caused endless confusion ever since. This concept is not fundamental, but is a common source of mistakes. You can learn how it works on a rainy day, but many people try to avoid it.
Literal: A literal is when you refer to a value by literally writing it down in your program. For example, 2 is a number literal, and "Banana" is a string literal.
Variable: A variable lets you refer to some value using a name. For example, let message = "Cows go moo". Now you can write message instead of repeating the same sentence every time in your code. You may later change message to point to another value, like message = "I am the walrus". Note this doesn’t change the value itself, but only where the message points to, like a “wire”. It pointed to "Cows go moo", and now it points to "I am the walrus".
- Scope: It would suck if there could only be one
messagevariable in the whole program. Instead, when you define a variable, it becomes available in a part of your program. That part is called a “scope”. There are rules about how scope works, but usually you can search for the closest{and}braces around where you define the variable. That “block” of code is its scope.
- Assignment: When we write
message = "I am the walrus", we change themessagevariable to point to"I am the walrus"value. This is called an assignment, writing, or setting the variable.
letvsconstvsvar: Usually you wantlet. If you want to forbid assignment to this variable, you can useconst. (Some codebases and coworkers are pedantic and force you to useconstwhen there is only one assignment.) Avoidvarif you can because its scoping rules are confusing.
Object: An object is a special kind of value in JavaScript. The cool thing about objects is that they can have connections to other values. For example, a {flavor: "vanilla"} object has a flavor property that points to the "vanilla" value. Think of an object as “your own” value with “wires” from it.
- Property: A property is like a “wire” sticking from an object and pointing to some value. It might remind you of a variable: it has a name (like
flavor) and points to a value (like"vanilla"). But unlike a variable, a property “lives” in the object itself rather than in some place in your code (scope). A property is considered a part of the object — but the value it points to is not.
- Object Literal: An object literal is a way to create an object value by literally writing it down in your program, like
{}or{flavor: "vanilla"}. Inside{}, we can have multipleproperty: valuepairs separated by commas. This lets us set up where the property “wires” point to from our object.
- Object Identity: We mentioned earlier that
2is equal to2(in other words,2 === 2) because whenever we write2, we “summon” the same value. But whenever we write{}, we will always get a different value! So{}is not equal to another{}. Try this in console:{} === {}(the result is false). When the computer meets2in our code, it always gives us the same2value. However, object literals are different: when a computer meets{}, it creates a new object, which is always a new value. So what is object identity? It’s yet another term for equality, or same-ness of values. When we say “aandbhave the same identity”, we mean “aandbpoint to the same value” (a === b). When we say “aandbhave different identities”, we mean “aandbpoint to different values” (a !== b).
- Dot Notation: When you want to read a property from an object or assign to it, you can use the dot (
.) notation. For example, if a variableiceCreampoints to an object whose propertyflavorpoints to"chocolate", writingiceCream.flavorwill give you"chocolate".
- Bracket Notation: Sometimes you don’t know the name of the property you want to read in advance. For example, maybe sometimes you want to read
iceCream.flavorand sometimes you want to readiceCream.taste. The bracket ([]) notation lets you read the property when its name itself is a variable. For example, let’s say thatlet ourProperty = 'flavor'. TheniceCream[ourProperty]will give us"chocolate". Curiously, we can use it when creating objects too:{ [ourProperty]: "vanilla" }.
[...]