Javascript Types
Primitive types (typeof
)
- Boolean
- Number (in JS, numbers are stored as floats)
- BigInt
- String
- Symbol
- undefined
**Boolean**
**Boolean**
s represent values that are either **true**
or **false**
. These are used for conditionals and logical operations using the AND (**&&**
), OR (**||**
) and NOT (**!**
) operators.
In JavaScript, some values of different types are considered "falsy", which means if you were to cast the value into a **Boolean**
using two NOT operators or with the **Boolean()**
built-in function, it would become **false**
, where every other value would become **true**
. I'll point out the "falsy" values for each type.
**Number**
**Number**
s in JavaScript are stored as floats, which means you use the same type for whole integers and decimals. JavaScript also has values for **Infinity**
, **-Infinity**
, and **NaN**
, or "Not a Number".
Both **0**
and **NaN**
are "falsy" values. **NaN**
is a little confusing. It's used to represent values that shouldn't exist or are imaginary, like **Math.sqrt(-1)**
. Even though **NaN**
literally means "Not a Number", it's type is still **Number**
. You also can't check if a **NaN**
value is equal to **NaN**
To check if a **Number**
is **NaN**
, you can use the **Number.isNaN()**
method.
Number.isNaN(imaginaryNumber); // true
**BigInt**
Since **Number**
s are limited in how big they can be, JavaScript has a separate type for very large integers. **BigInt**
s were introduce to JavaScript in ES2019 and are created by appending **n**
to the end of a **Number**
integer.
typeof 1337n; // "bigint"1337n === 1337; // false
The **BigInt**
value **0n**
is "falsy"
**String**
**String**
s store text data. You can create string literals with single quotes ('), double quotes ("), and backticks ().
Strings in JavaScript are immutable, which means once a string is created, you cannot mutate it to change it. An empty string (
""`) is the only falsy string value.
**Symbol**
**Symbol**
s are unique and immutable, which means each **Symbol**
is not equal to any other **Symbol**
. You can give a **Symbol**
a description when you create it, but that is not required.
let symbol1 = Symbol("Apple");let symbol2 = Symbol("Apple");symbol1 === symbol2; // falsetypeof symbol1; // "symbol"
**undefined**
** & ****null**
**undefined**
is its own types, is falsy. **undefined**
represents uninitialized values, including properties of **object**
s that don't have a value.
**null**
is an extra type used to represent the absence of value. Due to a bug in JavaScript, checking the type of **null**
with **typeof**
will return **object**
. It's kind of silly, but there are websites out there that expect this behavior. As Hyrum's Law states, if there's something wrong with the system, someone will come to depend on that flaw. Fortunately, you can compare **null**
to itself.
typeof undefined; // "undefined"let nullish = null;typeof nullish; // "object"nullish === null; //true
Bugs are often created when JavaScript tries to access **object**
properties on a **null**
or **undefined**
value. Later on we'll see how TypeScript can help us avoid those bugs.
JavaScript also has structural types, which means we can construct different shapes of the primitive types to represent more complex data structures.
**Object**
**Object**
is the most versatile type in JavaScript. An **Object**
can have any number of properties, each with its own value. This allows you to create unique and interesting data structures. **Object**
s typically use **String**
s for indexing the properties, but **Symbol**
s can be used as well. A property's value can be any type.
All of the other types we've looked at so far can be directly compared by value, but objects (and object-like values) are compared by reference. This means two objects that have the same shape aren't considered equal.
**Array**
**Array**
s are technically the same type as **Object**
s, but they are different enough that we'll treat them as separate types. **Array**
s store data, but use **Number**
s instead of **String**
s for indexing properties. This means that the data stored in **Array**
s is ordered.
We can check if a value is an array using the **Array.isArray()**
method.
**Function**
Functions are defined blocks of code that you can call from elsewhere in your program. They can take parameters and have a return value. One of the best things about JavaScript is that functions can be treated as values. That means you can pass them between functions or use them whenever you want. That means that **Function**
s are their own type as well.
typeof function () {}; // "function"typeof (() => {}); // "function
**Classes**
Classes were introduced to JavaScript in ES2015 and serve as syntactic sugar around JavaScript's Prototypal inheritance system. We'll talk more about classes later in the course, but for now we can look at the types that classes generate.
Classes can be defined with properties and given a constructor which initializes instances of that class. Within the class, we can use the special **this**
variable to access properties on the class instance. Since the class constructor is what we call when creating a new instance of a class, the type of a class is **Function**
. Instances of a class are **Object**
s.
If we want to see if an object is an instance of a specific class, we can use the **instanceof**
operator.
motorcycle instanceof Car; // true
We'll look at classes more in-depth in a later section.