Literals, Variables, Constants, and Data Types

Literals, Variables, Constants, and Data Types 


This chapter is about data, and how we translate data into a format that JavaScript
can understand.
You’re probably aware that all data is ultimately represented inside a computer as long
sequences of ones and zeros—but for most day-to-day tasks, we want to think about
data in a way that’s more natural to us: numbers, text, dates, and so on. We will call
these abstractions data types.
Before we dive into the data types available in JavaScript, we will discuss variables,
constants, and literals, which are the mechanisms available to us in JavaScript for
holding data.
The importance of vocabulary is often overlooked when you’re
learning to program. While it may not seem important to understand
how a literal differs from a value, or a statement from an
expression, not knowing these terms will hamper your ability to
learn. Most of these terms are not specific to JavaScript, but are
commonly understood in computer science. Having a good grasp
of the concepts is important, of course, but paying attention to
vocabulary makes it easy for you to transfer your knowledge to
other languages, and learn from more sources.
Variables and Constants
A variable is essentially a named value, and as the name implies, the value can change
at any time. For example, if we’re working on a climate control system, we might have
a variable called currentTempC:

let currentTempC = 22; // degrees Celsius
The let keyword is new in ES6; prior to ES6, the only option was
the var keyword, which we will discuss in Chapter 7.
This statement does two things: it declares (creates) the variable currentTempC and
assigns it an initial value. We can change the value of currentTempC at any time:
currentTempC = 22.5;
Note that we don’t use let again; let specifically declares a variable, and you can only
do it once.
With numbers, there’s no way to associate units with the value.
That is, there’s no language feature that allows us to say that
currentTempC is in degrees Celsius, thereby producing an error if
we assign a value in degrees Fahrenheit. For this reason, I chose to
add “C” to the variable name to make it clear that the units are
degrees Celsius. The language can’t enforce this, but it’s a form of
documentation that prevents casual mistakes.
When you declare a variable, you don’t have to provide it with an initial value. If you
don’t, it implicitly gets a special value, undefined:
let targetTempC; // equivalent to "let targetTempC = undefined";
You can also declare multiple variables with the same let statement:
let targetTempC, room1 = "conference_room_a", room2 = "lobby";
In this example, we’ve declared three variables: targetTempC isn’t initialized with a
variable, so it implicitly has the value undefined; room1 is declared with an initial
value of "conference_room_a"; and room2 is declared with an initial value of
"lobby". room1 and room2 are examples of string (text) variables.
A constant (new in ES6) also holds a value, but unlike a variable, can’t be changed
after initialization. Let’s use a constant to express a comfortable room temperature
and a maximum temp (const can also declare multiple constants):
const ROOM_TEMP_C = 21.5, MAX_TEMP_C = 30;
It is conventional (but not required) for constants that refer to a specific number or
string to be named with all uppercase letters and underscores. This makes them easy
to spot in your code, and is a visual cue that you shouldn’t try to change their value.

Variables or Constants: Which to Use?
In general, you should prefer constants over variables. You’ll find that more often
than not you want a handy name for some piece of data, but you don’t need its value
to change. The advantage of using constants is that it makes it harder to accidentally
change the value of something that shouldn’t be changed. For example, if you’re
working on a part of your program that performs some kind of action on a user, you
might have a variable called user. If you’re dealing with only one user, it would probably
indicate an error in your code if the value of user changed. If you were working
with two users, you might call them user1 and user2, instead of simply reusing a single
variable user.
So your rule of thumb should be to use a constant; if you find you have a legitimate
need to change the value of the constant, you can always change it to a variable.
There is one situation in which you will always want to use variables instead of constants:
variables used in loop control (which we’ll learn about in Chapter 4). Other
situations where you might want to use variables are when the value of something is
naturally changing over time (such as targetTempC or currentTemp in this chapter).
If you get in the habit of preferring constants, however, you might be surprised by
how seldom you really need a variable.
In the examples in this book, I have tried to use constants instead of variables whenever
possible.
Identifier Names
Variable and constant names (as well as function names, which we’ll cover in Chapter
6) are called identifiers, and they have naming rules:
• Identifiers must start with a letter, dollar sign ($), or underscore (_).
• Identifiers consist of letters, numbers, the dollar sign ($), and underscore (_).
• Unicode characters are allowed (for example, π or ö).
• Identifiers cannot be a reserved word (see Appendix A).
Note that the dollar sign is not a special character the way it is in some other languages:
it’s simply another character you can use in identifier names (many libraries,
such as jQuery, have taken advantage of this, and used the dollar sign by itself as an
identifier).
Reserved words are words that JavaScript might confuse with part of the language.
For example, you can’t have a variable called let.
There’s no single convention for JavaScript identifiers, but the two most common are:

Camel case
currentTempC, anIdentifierName (so named because the capital letters look like
the humps in a camel’s back).
Snake case
current_temp_c, an_identifier_name (slightly less popular).
You can use whichever convention you prefer, but consistency is a good idea: select
one and stick with it. If you are working on a team or making your project available
to a community, try choosing whatever the preferred convention is.
It is also advisable to adhere to the following conventions:
• Identifiers shouldn’t start with a capital letter except for classes (which we’ll cover
in Chapter 9).
• Very often, identifiers that start with one or two underscores are used to represent
special or “internal” variables. Unless you need to create your own special
category of variables, avoid starting variable names with an underscore.
• When using jQuery, identifiers that start with a dollar sign conventionally refer
to jQuery-wrapped objects (see Chapter 19).
Literals
We’ve already seen some literals: when we gave currentTempC a value, we provided a
numeric literal (22 at initialization, and 22.5 in the next example). Likewise, when we
initialized room1, we provided a string literal ("conference_room_a"). The word literal
means that you’re providing the value directly in the program. Essentially, a literal
is a way to create a value; JavaScript takes the literal value you provide and creates
a data value from it.
It’s important to understand the difference between a literal and an identifier. For
example, think back to our earlier example where we created a variable called room1,
which had the value "conference_room_a". room1 is an identifier (referring to a constant),
and "conference_room_a" is a string literal (and also the value of room1). Java‐
Script is able to distinguish the identifier from the literal by the use of quotation
marks (numbers don’t need any sort of quotation because identifiers can’t start with a
number). Consider the following example:
let room1 = "conference_room_a"; // "conference_room_a" (in quotes) is
// a literal
let currentRoom = room1; // currentRoom now has the same value
// as room1 ("conference_room_a")

let currentRoom = conference_room_a; // produces an error; no identifier
// called conference_room_a exists
You can use a literal anywhere you can use an identifier (where a
value is expected). For example, in our program, we could just use
the numeric literal 21.5 everywhere instead of using ROOM_TEMP_C.
If you use the numeric literal in a couple places, this may be OK.
But if you use it in 10 or 100 places, you should be using a constant
or variable instead: it makes your code easier to read, and you can
change the value in one place instead of many.
It is up to you, the programmer, to decide what to make a variable and what to make
a constant. Some things are quite obviously constants—such as the approximate value
of π (the ratio of a circle’s circumference to its diameter), or DAYS_IN_MARCH. Other
things, such as ROOM_TEMP_C, are not quite as obvious: 21.5°C might be a perfectly
comfortable room temperature for me, but not for you, so if this value is configurable
in your application, you would make it a variable instead.
Primitive Types and Objects
In JavaScript, values are either primitives or objects. Primitive types (such as string
and number) are immutable. The number 5 will always be the number 5; the string
"alpha" will always be the string "alpha". This seems obvious for numbers, but it
often trips people up with strings: when people concatenate strings together ("alpha"
+ "omega"), they sometimes think it’s the same string, just modified. It is not: it is a
new string, in the same way that 6 is a different number than 5. There are six primitive
types that we will cover:
• Number
• String
• Boolean
• Null
• Undefined
• Symbol
Note that immutability doesn’t mean the contents of a variable can’t change:
let str = "hello";
str = "world";
First str is initialized with the (immutable) value "hello", and then it is assigned a
new (immutable) value, "world". What’s important here is that "hello" and "world"
are different strings; only the value that str holds has changed. Most of the time, this
distinction is academic, but the knowledge will come in handy later when we discuss
functions in Chapter 6.
In addition to these six primitive types, there are objects. Unlike primitives, objects
can take on different forms and values, and are more chameleon-like.
Because of their flexibility, objects can be used to construct custom data types. As a
matter of fact, JavaScript provides some built-in object types. The built-in object
types we’ll cover are as follows:
• Array
• Date
• RegExp
• Map and WeakMap
• Set and WeakSet
Lastly, the primitive types number, string, and boolean have corresponding object
types, Number, String, and Boolean. These corresponding objects don’t actually store
a value (that’s what the primitive does), but rather provide functionality that’s related
to the corresponding primitive. We will discuss these object types along with their
primitives.
Numbers
While some numbers (like 3, 5.5, and 1,000,000) can be represented accurately by a
computer, many numbers are necessarily approximations. For example, π cannot be
represented by a computer at all, because its digits are infinite and do not repeat.
Other numbers, such as 1/3, can be represented by special techniques, but because of
their forever repeating decimals (3.33333…), they are normally approximated as well.
JavaScript—along with most other programming languages—approximates real numbers
through a format called IEEE-764 double-precision floating-point (which I will
refer to simply as a “double” from here on out). The details of this format are beyond
the scope of this book, but unless you are doing sophisticated numerical analysis, you
probably don’t need to understand them. However, the consequences of the approximations
required by this format often catch people off guard. For example, if you ask
JavaScript to calculate 0.1 + 0.2, it will return 0.30000000000000004. This does not
mean that JavaScript is “broken” or bad at math: it’s simply an unavoidable consequence
of approximating infinite values in finite memory.


JavaScript is an unusual programming language in that it only has this one numeric
data type.1 Most languages have multiple integer types and two or more floating-point
types. On one hand, this choice simplifies JavaScript, especially for beginners. On the
other hand, it reduces JavaScript’s suitability for certain applications that require the
performance of integer arithmetic, or the precision of fixed-precision numbers.
JavaScript recognizes four types of numeric literal: decimal, binary, octal, and hexadecimal.
With decimal literals, you can express integers (no decimal), decimal numbers,
and numbers in base-10 exponential notation (an abbreviation of scientific
notation). In addition, there are special values for infinity, negative infinity, and “not
a number” (these are not technically numeric literals, but they do result in numeric
values, so I am including them here):
let count = 10; // integer literal; count is still a double
const blue = 0x0000ff; // hexadecimal (hex ff = decimal 255)
const umask = 0o0022; // octal (octal 22 = decimal 18)
const roomTemp = 21.5; // decimal
const c = 3.0e6; // exponential (3.0 × 10^6 = 3,000,000)
const e = -1.6e-19; // exponential (-1.6 × 10^-19 = 0.00000000000000000016)
const inf = Infinity;
const ninf = -Infinity;
const nan = NaN; // "not a number"
No matter what literal format you use (decimal, hexadecimal, exponential,
etc.), the number that gets created is stored in the same format:
a double. The various literal formats simply allow you to
specify a number in whatever format is convenient. JavaScript has
limited support for displaying numbers in different formats, which
we’ll discuss in Chapter 16.
The mathematicians in the crowd might be calling foul: infinity is not a number!
Indeed, it isn’t; but of course, neither is NaN. These are not numbers you do computation
with; rather, they are available as placeholders.
In addition, there are some useful properties of the corresponding Number object that
represent important numeric values:
const small = Number.EPSILON; // the smallest value that can be
// added to 1 to get a distinct number
// larger than 1, approx. 2.2e-16
const bigInt = Number.MAX_SAFE_INTEGER; // the largest representable integer
const max = Number.MAX_VALUE; // the largest representable number
const minInt = Number.MIN_SAFE_INTEGER; // the smallest representable integer
const min = Number.MIN_VALUE; // the smallest representable number
const nInf = Number.NEGATIVE_INFINITY; // the same as -Infinity

const nan = Number.NaN; // the same as NaN
const inf = Number.POSITIVE_INFINITY; // the same as Infinity
We’ll discuss the importance of these values in Chapter 16.
Strings
A string is simply text data (the word string comes from “string of characters”—a
word originally used in the late 1800s by typesetters, and then later by mathematicians,
to represent a sequence of symbols in a definite order).
Strings in JavaScript represent Unicode text. Unicode is a computing industry standard
for representing text data, and includes code points for every character or symbol
in most known human languages (including “languages” that might surprise you,
such as Emoji). While Unicode itself is capable of representing text in any language,
that does not mean that the software rendering the Unicode will be capable of rendering
every code point correctly. In this book, we’ll stick to fairly common Unicode
characters that are most likely available in your browser and console. If you are working
with exotic characters or languages, you’ll want to do additional research on Unicode
to understand how code points are rendered.
In JavaScript, string literals are represented with single quotes, double quotes, or
backticks.2 The backtick was introduced in ES6 to enable template strings, which we
will cover shortly.
Escaping
When you’re trying to represent text data in a program that’s made up of text data,
the problem is always distinguishing text data from the program itself. Setting off
strings within quotes is a start, but what if you want to use quotes in a string? To solve
this problem, there needs to be a method of escaping characters so they are not taken
as string termination. Consider the following examples (which do not require escaping):
const dialog = 'Sam looked up, and said "hello, old friend!", as Max walked in.';
const imperative = "Don't do that!";
In dialog, we can use double quotes without fear because our string is set off with
single quotes. Likewise, in imperative, we can use an apostrophe because the string
is set off with double quotes. But what if we needed to use both? Consider:
// this will produce an error
const dialog = "Sam looked up and said "don't do that!" to Max.";

This dialog string will fail no matter which quotation mark we choose. Fortunately,
we can escape quotation marks with a backslash (\), which is a signal to JavaScript
that the string is not ending. Here’s the preceding example rewritten to use both types
of quotation marks:
const dialog1 = "He looked up and said \"don't do that!\" to Max.";
const dialog2 = 'He looked up and said "don\'t do that!" to Max.';
Then, of course, we get into the chicken-and-egg problem that arises when we want
to use a backslash in our string. To solve this problem, a backslash can escape itself:
const s = "In JavaScript, use \\ as an escape character in strings.";
Whether you use single or double quotes is up to you. I generally prefer double quotation
marks when I’m writing text that might be presented to the user, because I use
contractions (like don’t) more often than I use double quotation marks. When I’m
expressing HTML inside a JavaScript string, I tend to prefer single quotation marks
so that I can use double quotation marks for attribute values.
Special Characters
The backslash is used for more than simply escaping quotation marks: it is also used
to represent certain nonprintable characters, such as newlines and arbitrary Unicode
characters. Table 3-1 lists the commonly used special characters.
Table 3-1. Commonly used special characters
Code Description Example
\n Newline (technically a line feed character: ASCII/Unicode
10)
"Line1\nLine2"
\r Carriage return (ASCII/Unicode 13) "Windows line 1\r\nWindows line 2"
\t Tab (ASCII/Unicode 9) "Speed:\t60kph"
\' Single quote (note that you can use this even when not
necessary)
"Don\'t"
\" Double quote (note that you can use this even when not
necessary)
'Sam said \"hello\".'
\` Backtick (or “accent grave”; new in ES6) `New in ES6: \` strings.`
\$ Dollar sign (new in ES6) `New in ES6: ${interpolation}`
\\ Backslash "Use \\\\ to represent \\!"


Code Description Example
\uXXXX Arbitrary Unicode code point (where +XXXX+ is a
hexadecimal code point)
"De Morgan’s law: \u2310(P \u22c0
Q) \u21D4 (\u2310P) \u22c1
(\u2310Q)"
\xXX Latin-1 character (where +XX+ is a hexadecimal Latin-1
code point)
"\xc9p\xe9e is fun, but foil is
more fun."
Note that the Latin-1 character set is a subset of Unicode, and any Latin-1 character
\xXX can be represented by the equivalent Unicode code point \u00XX. For hexadecimal
numbers, you may use lowercase or uppercase letters as you please; I personally
favor lowercase, as I find them easier to read.
You don’t need to use escape codes for Unicode characters; you can also enter them
directly into your editor. The way to access Unicode characters varies among editors
and operating systems (and there is usually more than one way); please consult your
editor or operating system documentation if you wish to enter Unicode characters
directly.
Additionally, there are some rarely used special characters, shown in Table 3-2. To my
recollection, I have never used any of these in a JavaScript program, but I include
them here for the sake of completeness.
Table 3-2. Rarely used special characters
Code Description Example
\0 The NUL character (ASCII/Unicode 0) "ASCII NUL: \0"
\v Vertical tab (ASCII/Unicode 11) "Vertical tab: \v"
\b Backspace (ASCII/Unicode 8) "Backspace: \b"
\f Form feed (ASCII/Unicode 12) "Form feed: \f"
Template Strings
A very common need is to express values in a string. This can be accomplished
through a mechanism called string concatenation:
let currentTemp = 19.5;
// 00b0 is the Unicode code point for the "degree" symbol
const message = "The current temperature is " + currentTemp + "\u00b0C";
Up until ES6, string concatenation was the only way to accomplish this (short of
using a third-party library). ES6 introduces string templates (also known as string
42 |

const multiline = `line1
line2
line3`;
For this reason, I avoid multiline string syntax: it forces me to either abandon indentation
that makes code easier to read, or include whitespace in my multiline strings
that I may not want. If I do want to break strings up over multiple lines of source
code, I usually use string concatenation:
const multiline = "line1\n" +
"line2\n" +
"line3";
This allows me to indent my code in an easy-to-read fashion, and get the string I
want. Note that you can mix and match types of strings in string concatenation:
const multiline = 'Current temperature:\n' +
`\t${currentTemp}\u00b0C\n` +
"Don't worry...the heat is on!";
Numbers as Strings
If you put a number in quotation marks, it’s not a number—it’s a string. That said,
JavaScript will automatically convert strings that contain numbers to numbers as necessary.
When and how this happens can be very confusing, as we will discuss in
Chapter 5. Here’s an example that illustrates when this conversion happens, and when
it doesn’t:
const result1 = 3 + '30'; // 3 is converted to a string; result is string '330'
const result2 = 3 * '30'; // '30' is converted to a number; result is numeric 90
As a rule of thumb, when you want to use numbers, use numbers (that is, leave off the
quotes), and when you want to use strings, use strings. The gray area is when you’re
accepting user input, which almost always comes as a string, leaving it up to you to
convert to a number where appropriate. Later in this chapter, we will discuss techniques
for converting among data types.
Booleans
Booleans are value types that have only two possible values: true and false. Some
languages (like C) use numbers instead of booleans: 0 is false and every other number
is true. JavaScript has a similar mechanism, allowing any value (not just numbers)
to be considered “truthy” or “falsy,” which we’ll discuss further in Chapter 5.
Be careful not to use quotation marks when you intend to use a boolean. In particular,
a lot of people get tripped up by the fact that the string "false" is actually truthy!
Here’s the proper way to express boolean literals:

let heating = true;
let cooling = false;
Symbols
New in ES6 are symbols: a new data type representing unique tokens. Once you create
a symbol, it is unique: it will match no other symbol. In this way, symbols are like
objects (every object is unique). However, in all other ways, symbols are primitives,
lending themselves to useful language features that allow extensibility, which we’ll
learn more about in Chapter 9.
Symbols are created with the Symbol() constructor.4 You can optionally provide a
description, which is just for convenience:
const RED = Symbol();
const ORANGE = Symbol("The color of a sunset!");
RED === ORANGE // false: every symbol is unique
I recommend using symbols whenever you want to have a unique identifier that you
don’t want inadvertently confused with some other identifier.
null and undefined
JavaScript has two special types, null and undefined. null has only one possible
value (null), and undefined has only one possible value (undefined). Both null and
undefined represent something that doesn’t exist, and the fact that there are two separate
data types has caused no end of confusion, especially among beginners.
The general rule of thumb is that null is a data type that is available to you, the programmer,
and undefined should be reserved for JavaScript itself, to indicate that
something hasn’t been given a value yet. This is not an enforced rule: the undefined
value is available to the programmer to use at any time, but common sense dictates
that you should be extremely cautious in using it. The only time I explicitly set a variable
to undefined is when I want to deliberately mimic the behavior of a variable that
hasn’t been given a value yet. More commonly, you want to express that the value of a
variable isn’t known or isn’t applicable, in which case null is a better choice. This may
seem like splitting hairs, and sometimes it is—the beginning programmer is advised
to use null when unsure. Note that if you declare a variable without explicitly giving
it a value, it will have a value of undefined by default. Here are examples of using
null and undefined literals:

Objects
Unlike the immutable primitive types, which only ever represent one value, objects
can represent multiple or complex values, and can change over their lifetime. In
essence, an object is a container, and the contents of that container can change over
time (it’s the same object with different contents). Like the primitive types, objects
have a literal syntax: curly braces ({ and }). Because curly braces come in pairs, it
allows us to express an object’s contents. Let’s start with an empty object:
const obj = {};
We can name our object anything we want, and normally you
would use a descriptive name, such as user or shoppingCart. We’re
just learning the mechanics of objects, and our example doesn’t
represent anything specific so we just generically call it obj.
The contents of an object are called properties (or members), and properties consist of
a name (or key) and value. Property names must be strings or symbols, and values can
be any type (including other objects). Let’s add a property color to obj:
obj.size; // undefined
obj.color; // "yellow"
To use the member access operator, the property name must be a valid identifier. If
you want property names that are not valid identifiers, you have to use the computed
member access operator (you can also use this for valid identifiers):
obj["not an identifier"] = 3;
obj["not an identifier"]; // 3
obj["color"]; // "yellow"
You also use the computed member access operator for symbol properties:
const SIZE = Symbol();
obj[SIZE] = 8;
obj[SIZE]; // 8
At this point, obj contains three properties with keys "color" (a string that is a valid
identifier), "not an identifier" (a string that is not a valid identifier), and SIZE (a
symbol).


If you’re following along in a JavaScript console, you may notice
that the console doesn’t list the SIZE symbol as a property of obj. It
is (you can verify this by typing obj[SIZE]), but symbol properties
are handled differently and are not displayed by default. Also note
that the key for this property is the symbol SIZE, not the string
"SIZE". You can verify this by typing obj.SIZE = 0 (the member
access property always operates on string properties) and then
obj[SIZE] and obj.SIZE (or obj["SIZE"]).
At this juncture, let’s pause and remind ourselves of the differences between primitives
and objects. Throughout this section, we have been manipulating and modifying
the object contained by the variable obj, but obj has been pointing to the same object
all along. If obj had instead contained a string or a number or any other primitive, it
would be a different primitive value every time we change it. In other words, obj has
pointed to the same object all along, but the object itself has changed.
In the instance of obj, we created an empty object, but the object literal syntax also
allows us to create an object that has properties right out of the gate. Inside the curly
braces, properties are separated by commas, and the name and value are separated by
a colon:
const sam1 = {
name: 'Sam',
age: 4,
};
const sam2 = { name: 'Sam', age: 4 }; // declaration on one line
const sam3 = {
name: 'Sam',
classification: { // property values can
kingdom: 'Anamalia', // be objects themselves
phylum: 'Chordata',
class: 'Mamalia',
order: 'Carnivoria',
family: 'Felidae',
subfaimily: 'Felinae',
genus: 'Felis',
species: 'catus',
},
};
In this example, we’ve created three new objects that demonstrate the object literal
syntax. Note that the properties contained by sam1 and sam2 are the same; however,
they are two distinct objects (again, contrast to primitives: two variables that both contain
the number 3 refer to the same primitive). In sam3, property classification is
itself an object. Consider the different ways we can access Sam the cat’s family (it also
doesn’t matter if we use single or double quotes or even backticks):

Objects can also contain functions. We’ll learn about functions in depth in Chapter 6,
but for now, what you need to know is that a function contains code (essentially a
subprogram). Here’s how we add a function to sam3:
sam3.speak = function() { return "Meow!"; };
We can now call that function by adding parentheses to it:
sam3.speak(); // "Meow!"
Lastly, we can delete a property from an object with the delete operator:
delete sam3.classification; // the whole classification tree is removed
delete sam3.speak; // the speak function is removed
If you’re familiar with object-oriented programming (OOP), you may be wondering
how JavaScript objects relate to OOP. For now, you should think of an object as a
generic container; we will discuss OOP in Chapter 9.
Number, String, and Boolean Objects
We mentioned earlier in this chapter that numbers, strings, and booleans have corresponding
object types (Number, String, and Boolean). These objects serve two purposes:
to store special values (such as Number.INFINITY), and to provide functionality
in the form of function. Consider the following:
const s = "hello";
s.toUpperCase(); // "HELLO"
This example makes it look like s is an object (we accessed a function property as if it
were). But we know better: s is a primitive string type. So how is this happening?
What JavaScript is doing is creating a temporary String object (which has a function
toUpperCase, among others). As soon as the function has been called, JavaScript discards
the object. To prove the point, let’s try to assign a property to a string:
const s = "hello";
s.rating = 3; // no error...success?
s.rating; // undefined
JavaScript allows us to do this, making it seem like we’re assigning a property to the
string s. What’s really happening, though, is that we’re assigning a property to the
temporary String object that’s created. That temporary object is immediately discarded,
which is why s.rating is undefined.
This behavior will be transparent to you, and rarely (if ever) do you have to think
about it, but it can be useful to know what JavaScript is doing behind the scenes.


Arrays
In JavaScript, arrays are a special type of object. Unlike regular objects, array contents
have a natural order (element 0 will always come before element 1), and keys are
numeric and sequential. Arrays support a number of useful methods that make this
data type an extremely powerful way to express information, which we will cover in
Chapter 8.
If you’re coming from other languages, you’ll find that arrays in JavaScript are something
of a hybrid of the efficient, indexed arrays of C and more powerful dynamic
arrays and linked lists. Arrays in JavaScript have the following properties:
• Array size is not fixed; you can add or remove elements at any time.
• Arrays are not homogeneous; each individual element can be of any type.
• Arrays are zero-based. That is, the first element in the array is element 0.
Because arrays are special types of objects with some extra functionality,
you can assign non-numeric (or fractional or negative)
keys to an array. While this is possible, it contradicts the intended
purpose of arrays, can lead to confusing behavior and difficult-todiagnose
bugs, and is best avoided.
To create an array literal in JavaScript, use square brackets, with the elements of the
array separated by commas:
const a1 = [1, 2, 3, 4]; // array containing numbers
const a2 = [1, 'two', 3, null]; // array containing mixed types
const a3 = [ // array on multiple lines
"What the hammer? What the chain?",
"In what furnace was thy brain?",
"What the anvil? What dread grasp",
"Dare its deadly terrors clasp?",
];
const a4 = [ // array containing objects
{ name: "Ruby", hardness: 9 },
{ name: "Diamond", hardness: 10 },
{ name: "Topaz", hardness: 8 },
];
const a5 = [ // array containing arrays
[1, 3, 5],
[2, 4, 6],
];
Arrays have a property length, which returns the number of elements in the array:
const arr = ['a', 'b', 'c'];
arr.length;


To access individual elements of an array, we simply use the numeric index of the element
inside square brackets (similar to how we access properties on an object):
const arr = ['a', 'b', 'c'];
// get the first element:
arr[0]; // 'a'
// the index of the last element in arr is arr.length-1:
arr[arr.length - 1]; // 'c'
To overwrite the value at a specific array index, you can simply assign to it:5
const arr = [1, 2, 'c', 4, 5];
arr[2] = 3; // arr is now [1, 2, 3, 4, 5]
In Chapter 8, we’ll learn many more techniques for modifying arrays and their
contents.
Trailing Commas in Objects and Arrays
The alert reader may have already noticed that in these code samples, when the content
of objects and arrays spans multiple lines, there is a trailing (or dangling or terminal)
comma:
const arr = [
"One",
"Two",
"Three",
];
const o = {
one: 1,
two: 2,
three: 3,
};
Many programmers avoid adding this because in early versions of Internet Explorer,
trailing commas produced an error (even though it has always been allowed in the
JavaScript syntax). I prefer trailing commas because I am frequently cutting and pasting
within arrays and objects, and adding things to the end of the object, so having
the trailing comma means I never need to remember to add a comma on the line
before; it’s simply always there. This is a hotly contested convention, and my preference
is just that: a preference. If you find the trailing comma troubling (or your team’s
style guide prohibits its use), by all means, omit it.

JavaScript Object Notation (JSON), a JavaScript-like data syntax
used quite frequently, does not allow trailing commas.
Dates
Dates and times in JavaScript are represented by the built-in Date object. Date is one
of the more problematic aspects of the language. Originally a direct port from Java
(one of the few areas in which JavaScript actually has any direct relationship to Java),
the Date object can be difficult to work with, especially if you are dealing with dates
in different time zones.
To create a date that’s initialized to the current date and time, use new Date():
const now = new Date();
now; // example: Thu Aug 20 2015 18:31:26 GMT-0700 (Pacific Daylight Time)
To create a date that’s initialized to a specific date (at 12:00 a.m.):
const halloween = new Date(2016, 9, 31); // note that months are
// zero-based: 9=October
To create a date that’s initialized to a specific date and time:
const halloweenParty = new Date(2016, 9, 31, 19, 0); // 19:00 = 7:00 pm
Once you have a date object, you can retrieve its components:
halloweenParty.getFullYear(); // 2016
halloweenParty.getMonth(); // 9
halloweenParty.getDate(); // 31
halloweenParty.getDay(); // 1 (Mon; 0=Sun, 1=Mon,...)
halloweenParty.getHours(); // 19
halloweenParty.getMinutes(); // 0
halloweenParty.getSeconds(); // 0
halloweenParty.getMilliseconds(); // 0
We will cover dates in detail in Chapter 15.
Regular Expressions
A regular expression (or regex or regexp) is something of a sublanguage of JavaScript.
It is a common language extension offered by many different programming languages,
and it represents a compact way to perform complex search and replace operations
on strings. Regular expressions will be covered in Chapter 17. Regular
expressions in JavaScript are represented by the RegExp object, and they have a literal
syntax consisting of symbols between a pair of forward slashes. Here are some examples
(which will look like gibberish if you’ve never seen a regex before):

// extremely simple email recognizer
const email = /\b[a-z0-9._-]+@[a-z_-]+(?:\.[a-z]+)+\b/;
// US phone number recognizer
const phone = /(:?\+1)?(:?\(\d{3}\)\s?|\d{3}[\s-]?)\d{3}[\s-]?\d{4}/;
Maps and Sets
ES6 introduces the data types Map and Set, and their “weak” counterparts, WeakMap
and WeakSet. Maps, like objects, map keys to values, but offer some advantages over
objects in certain situations. Sets are similar to arrays, except they can’t contain duplicates.
The weak counterparts function similarly, but they make functionality tradeoffs
in exchange for more performance in certain situations.
We will cover maps and sets in Chapter 10.
Data Type Conversion
Converting between one data type and another is a very common task. Data that
comes from user input or other systems often has to be converted. This section covers
some of the more common data conversion techniques.
Converting to Numbers
It’s very common to want to convert strings to numbers. When you collect input from
a user, it’s usually as a string, even if you’re collecting a numeric value from them.
JavaScript offers a couple of methods to convert strings to numbers. The first is to use
the Number object constructor:6
const numStr = "33.3";
const num = Number(numStr); // this creates a number value, *not*
// an instance of the Number object
If the string can’t be converted to a number, NaN will be returned.
The second approach is to use the built-in parseInt or parseFloat functions. These
behave much the same as the Number constructor, with a couple of exceptions. With
parseInt, you can specify a radix, which is the base with which you want to parse the
number. For example, this allows you to specify base 16 to parse hexadecimal numbers.
It is always recommended you specify a radix, even if it is 10 (the default). Both
parseInt and parseFloat will discard everything they find past the number, allowing
you to pass in messier input. Here are examples:


const a = parseInt("16 volts", 10); // the " volts" is ignored, 16 is
// parsed in base 10
const b = parseInt("3a", 16); // parse hexadecimal 3a; result is 58
const c = parseFloat("15.5 kph"); // the " kph" is ignored; parseFloat
// always assumes base 10
A Date object can be converted to a number that represents the number of milliseconds
since midnight, January 1, 1970, UTC, using its valueOf() method:
const d = new Date(); // current date
const ts = d.valueOf(); // numeric value: milliseconds since
// midnight, January 1, 1970 UTC
Sometimes, it is useful to convert boolean values to 1 (true) or 0 (false). The conversion
uses the conditional operator (which we will learn about in Chapter 5):
const b = true;
const n = b ? 1 : 0;
Converting to String
All objects in JavaScript have a method toString(), which returns a string representation.
In practice, the default implementation isn’t particularly useful. It works well
for numbers, though it isn’t often necessary to convert a number to a string: that conversion
usually happens automatically during string concatenation or interpolation.
But if you ever do need to convert a number to a string value, the toString() method
is what you want:
const n = 33.5;
n; // 33.5 - a number
const s = n.toString();
s; // "33.5" - a string
Date objects implement a useful (if lengthy) toString() implementation, but most
objects will simply return the string "[object Object]". Objects can be modified to
return a more useful string representation, but that’s a topic for Chapter 9. Arrays,
quite usefully, take each of their elements, convert them to strings, and then join
those strings with commas:
const arr = [1, true, "hello"];
arr.toString(); // "1,true,hello"
Converting to Boolean
In Chapter 5, we’ll learn about JavaScript’s idea of “truthy” and “falsy,” which is a way
of coercing all values to true or false, so we won’t go into all those details here. But we
will see that we can convert any value to a boolean by using the “not” operator (!)
twice. Using it once converts the value to a boolean, but the opposite of what you
want; using it again converts it to what you expect. As with numeric conversion, you

can also use the Boolean constructor (again, without the new keyword) to achieve the
same result:
const n = 0; // "falsy" value
const b1 = !!n; // false
const b2 = Boolean(n); // false
Conclusion
The data types available to you in a programming language are your basic building
blocks for the kind of things you can express in the language. For most of your dayto-
day programming, the key points you want to take away from this chapter are as
follows:
• JavaScript has six primitive types (string, number, boolean, null, undefined, and
symbol) and an object type.
• All numbers in JavaScript are double-precision floating-point numbers.
• Arrays are special types of objects, and along with objects, represent very powerful
and flexible data types.
• Other data types you will be using often (dates, maps, sets, and regular expressions)
are special types of objects.
Most likely, you will be using strings quite a lot, and I highly recommend that you
make sure you understand the escaping rules for strings, and how string templates
work, before proceeding.

Comments