04. Count “values” (1)
In this section, we’ll delve into the JavaScript world and the values in it. But before we do that, we need to address an issue that we don’t want to talk about. Is the JavaScript world real?
JavaScript simulator
We live on an asteroid in a JavaScript world. When we ask the JavaScript world a question, it gives us the answer via the value. We certainly don’t remember by ourselves all these values, variables, lines, values — they all make up our world. The JavaScript world around us is definitely real to us – just as the world we live in is real to us. But sometimes, there is a moment of silence before the next line of code is executed, the interval between the next function call, something mysterious happens. In that moment, I saw a world bigger than ours.
Learn from the outside in
One way to learn about our JavaScript world is from the outside. Perhaps, you might focus on “literally” emulating the way the JavaScript world (a JavaScript engine) works. For example, you might learn that a text string (a value in the JavaScript world) is a sequence of bytes stored on a memory chip. This approach allows us to focus on the physical world of people and computers. Some tutorials take this approach. But we’re going to use a different approach.
Learning from the inside out
We’re going to study the JavaScript world from the inside, we’re going to bring ourselves into the JavaScript world mentally, and we’re going to observe its laws and experiment, just like physicists do in the physical universe. We’ll learn the nature of the JavaScript world, regardless of how it’s implemented. It’s similar to how physicists talk about the properties of stars without answering the question of whether the physical world is real, and that’s fine! We can still describe it in our own terms. Our mental models don’t try to answer questions like “How is memory represented in computer memory?” Because the answers keep changing! In fact, the answer to this question will change even if your program is running. If you hear simple instructions about how JavaScript “really” represents numbers, strings, or objects in memory, you’re probably wrong. For us, each string is a value, not a “pointer” or a “memory address,” but a value. In our JavaScript world, “values” are enough. Don’t use “memory cells” and other low-level metaphors to distract you from the precise high-level thinking model of JavaScript. If you are using a lower level language, don’t use intuitive thinking like “pass by reference”, “allocate by stack”, “copy on write” etc. These models of how computers work often make it harder to determine what may or may not happen in a JavaScript program. We’re only working on low-level details where it really matters. They can complement, rather than base, our models of thought. Instead, our mental model is based on the idea that our world is full of values. Each value belongs to one of several built-in types, some of which are primitive, and the values of these types are immutable. Variables are “lines” from names to values in code, and we’ll continue to build on that. For some strange phenomena, we don’t need to think too much about them, we need to focus on the question to ask and the function to call, I’d better do it! When we look at them, the stars are bright. Were they still there when we blinked? We shrugged. “Specific performance is as follows” :
Count “values”
Count von Count was my childhood favorite, and if you’re not familiar with Sesame Street, his favorite pastime was counting. Today, Count von Count will be working with us to evaluate every value in the JavaScript world. You might be wondering: What’s the point of calculating values? We’re not in arithmetic, are we? The essence of calculating values is to distinguish things from one another. When you clearly see that they are two different apples, you can only say that there are “two apples”. Distinguishing values from each other is key to understanding JavaScript equality – which will be our next topic. Just as Virgil guided Dante through the nine loops of hell, Count von Count will accompany us through JavaScript “celestial bodies” to satisfy different values: Bools, numbers, strings, etc. Consider viewing them on a sightseeing tour.
Undefined
We’ll start with the “Undefined” type, and Count von Count is happy to know that this type has only one value -Undefined.
console.log(typeof(undefined)); // "undefined"
Copy the code
let person = undefined;
console.log(person.mood); // TypeError!
Copy the code
That is all right. Fortunately, there is only one undefined in the entire JavaScript world. You may be wondering: why is it undefined but actually there? In the JavaScript world, it represents the concept of an unintentional missing value. You can use undefined in your own code just as you would use the value 2 or “hello”. However, undefined usually “comes naturally” too. In some cases, JavaScript will show you when it doesn’t know what value you want. For example, if you forget to assign a variable, it will point to undefined:
let bandersnatch;
console.log(bandersnatch); // undefined
Copy the code
console.log(jabberwocky); // ReferenceError!
let jabberwocky;
Copy the code
This has nothing to do with undefined. In fact, undefined is a normal raw value, such as 2 or “Hello.” Handle it carefully.
Null
let mimsy = null;
console.log(mimsy.mood); // TypeError!
Copy the code
console.log(typeof(null)); // "object" (a lie!)
Copy the code
You might think this means null is an object, don’t fall into this trap! This is a primitive value, does it behave differently than an object? Unfortunately, Typeof (NULL) is a historical accident and we must always accept it. In fact, null is used for intentionally missing values. Why both null and undefined? This is a convention, and JavaScript does not enforce it, but avoid both if possible! I don’t blame them.
Booleans
console.log(typeof(true)); // "boolean"
console.log(typeof(false)); // "boolean"
Copy the code
We can perform the following logical operations on them
let isSad = true;
letisHappy = ! isSad;// The opposite
let isFeeling = isSad || isHappy; // Is at least one of them true?
let isConfusing = isSad && isHappy; // Are both true?
Copy the code
Count von Count now wants to examine your mental model, open a drawing program or a piece of paper, and draw variables for the code snippet above, connecting values to them with a line. Do not scroll down until you have finished writing. . . . . . . . . . Check your answers against the picture below:
Numbers
false
console.log(typeof(28)); // "number"
console.log(typeof(3.14)); // "number"
console.log(typeof(- 140.)); // "number"
Copy the code
At first, the numbers don’t seem obvious. Let’s take a closer look!
Computer mathematics
Number types in JavaScript don’t behave exactly the way numbers do in regular math. Here’s a clip to prove it:
console.log(0.1 + 0.2= = =0.3); // false
console.log(0.1 + 0.2= = =0.30000000000000004); // true
Copy the code
This may seem very surprising! Contrary to popular belief, this does not mean that JavaScript numbers are wrong. This behavior is common in different programming languages. It even has a name: floating point math. You’ll find that JavaScript doesn’t implement the kind of numbers we use in real life. Floating point numbers are “computer math.” Don’t worry too much about the name or how it actually works, because few people know all the nuances of it, and that’s the point! It works well in practice and you don’t have to pay much attention to it most of the time. Nonetheless, let’s take a quick look at what makes it different.
Colors and numbers
Have you ever used a scanner to convert physical photos or documents into digital images or documents? This analogy helps us understand JavaScript numbers. Typically, scanners can distinguish up to 16 million colors. If you drew a picture with a red crayon and scanned it, the resulting image should also be red — but it’s the color our scanner picked as close to red as it could get from those 16 million colors. So if you have two red crayons that are slightly different colors, the scanner could be tricked into thinking they are exactly the same color! So, if you have two red crayons that are slightly different colors, the scanner might think they’re exactly the same color. From the example above, we learned that the scanner has a limited accuracy in color processing. Floating-point numbers are similar. In basic mathematics, there is an infinite set of numbers. However, it is finite in floating-point numbers (limited by machine bits). So when we write numbers in code or perform calculations with them, JavaScript picks the closest number it knows — just like our scanner handles colors. In other words, JavaScript treats numbers as numbers with finite precision. We can imagine all the JavaScript numbers on an axis. The closer we get to 0, the more accurate the numbers become, and the closer they sit to each other.
The smaller the whole number, the more the number of decimal parts, so the number of 0-1 is the largest. The following figure shows the distribution of finite floating point numbers.
As we move from zero in either direction, we start to lose accuracy. At some point, even the two closest JavaScript numbers are farther apart than 1:
console.log(Number.MAX_SAFE_INTEGER); / / 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1); / / 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2); / / 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 3); / / 9007199254740994
console.log(Number.MAX_SAFE_INTEGER + 4); / / 9007199254740996
console.log(Number.MAX_SAFE_INTEGER + 5); / / 9007199254740996
Copy the code
Fortunately, any integer between number.min_safe_INTEGER and number.max_safe_INTEGER is accurate. That’s why 10 + 20 === 30 is correct. However, when we write 0.1 or 0.2, we don’t get the exact 0.1 and 0.2. We get the closest number available in JavaScript. They are almost identical, but there may be slight differences. These tiny differences add up, which is why 0.1+0.2 doesn’t give you exactly the same number as writing 0.3. If this still confuses you, don’t worry, you can learn a lot more about floating point math, but you definitely knew a lot more before I started writing this guide! Unless you work on a financial APP, you probably don’t need to worry about this.
Special digital
It is worth noting that floating point numbers include some special numbers. You might occasionally encounter NaN, Infinity, -infinity, and -0, which exist because sometimes you might perform operations like 1/0, and JavaScript needs to represent their results in some way. Floating-point mathematics standards specify how they work and what happens when they are used. The following code shows how special numbers can appear:
let scale = 0;
let a = 1 / scale; // Infinity
let b = 0 / scale; // NaN
let c = -a; // -Infinity
let d = 1 / c; / / - 0
Copy the code
NaN is of particular interest among these special numbers. NaN is the result of 0/0 and some other invalid numbers, meaning “not a number.” You may be confused as to why NaN is a number:
console.log(typeof(NaN)); // "number"
Copy the code
However, there are no gimmicks here. From a JavaScript perspective, NaN is a numeric value; it is not null, undefined, string, or some other type. But in floating-point numbers, the word is called “not a number,” so it’s a number type, but it happens to be called “not a number,” because it represents an invalid calculation. It’s not common to write code with these special numbers. However, they can occur due to coding errors. So it’s good to know they exist.
To be continued
This section is divided into two parts. We are at the end of Part 1. Now let’s take a break and review how many value types we’ve counted so far!
- Undefined: has only one value
undefined
. - Null: has only one value,
null
. - Booleans: Two values:
true
andfalse
. - Numbers: Each floating point number represents a numeric value
We also learned some interesting facts about JavaScript numbers:
- Not all numbers can be represented perfectly in JavaScript. Their fractional parts provide greater precision closer to 0 and less precision farther away from 0. We could say that they float the decimal point.
- ** Invalid mathematical operations like 1/0 or 0/0 produce numbers that are special. **NaN is one such number. They can be caused by coding errors.
- Typeof (NaN) is a number because NaN is a number type. It’s called “not a number” because it represents the idea of “invalid” numbers.
exercises
This section also includes questions for you to practice on! Click here to reinforce this mindset with a few short exercises. Don’t skip them! Even though you may be familiar with different types of values, these exercises will help you solidify the mental model we’re building. We need this foundation before moving on to more complex topics.