Values, variables and types

Introduction

A value's type decides what you can do with it. You can multiply numbers and shout text in capitals, but not the other way round. JavaScript is relaxed about types: it will convert values on its own, and most of the strange results people complain about come from that. Once you know the handful of rules, these results stop being surprises.

How it works

Three ways to declare a variable.

KeywordCan change?Where it is visibleUse it
constno: it always holds the same valuethe block { ... } it is inby default
letyesthe block it is inwhen the value must change
varyesthe whole functionnot in new code (older programs use it)

const means the variable cannot be given a new value. If it holds an object or array, that object can still change inside, as you will see in the arrays lesson. Why prefer it? When you read const, you know that the name means the same thing everywhere below, so you have one less thing to keep track of.

The types of values.

TypeExamplestypeof gives
number42, 3.14, -7, NaN (not a number)"number"
string"hi", 'single', `template`"string"
booleantrue, false"boolean"
undefineda variable with no value yet"undefined"
null"no value", on purpose"object" (a famous old mistake in the language)
object{ a: 1 }, [1, 2], functions"object" or "function"

JavaScript has one number type for whole numbers and decimals. Decimals are stored in binary, which cannot hold most decimal fractions exactly, so they are approximate: 0.1 + 0.2 is 0.30000000000000004. To show a tidy result, round it: Math.round(x * 100) / 100 keeps two decimal places.

== and ===. === (strict equality) is true only when both the type and the value match. == first converts values to the same type, with surprising results, so modern code uses === and !==:

// == converts first; === does not.
console.log(5 == "5", 5 === "5");
console.log(0 == "", 0 === "");
console.log(null == undefined, null === undefined);
console.log("5" + 1, "5" - 1);
console.log(Number("5") + 1, String(5) + 1);
console.log(Number("hello"));    // NaN: not a number
Open in compiler

Mixing text and numbers. + with a string joins text, so "5" + 1 is "51", while - only does arithmetic, so "5" - 1 is 4. Convert on purpose with Number(...) and String(...).

Checking a conversion. Number("hello") gives NaN. NaN is the one value that is not equal to itself, so x === NaN is always false. Use Number.isNaN(x) instead.

Syntax

const pi = 3.14;              // never changes
let score = 0;                // may change
typeof score                  // "number"
Number("42")                  // 42
String(42)                    // "42"
Number.isNaN(Number("abc"))   // true

Example

Template strings use backticks and put values inside, as in this example.

// The types of values, and typeof.
const name = "Rahim";
const age = 21;
const enrolled = true;
let grade;                       // no value yet: undefined
const nothing = null;
console.log(typeof name, typeof age, typeof enrolled, typeof grade, typeof nothing);
const intro = `${name} is ${age} years old`;   // a template string
console.log(intro);
console.log(0.1 + 0.2, "Dhaka".length, "Dhaka".toUpperCase());
Open in compiler

Line by line

  1. Three const lines create a string, a number and a boolean.
  2. let grade; creates a variable with no value, so it is undefined.
  3. const nothing = null stores "no value" on purpose.
  4. The typeof line prints the type of each. Notice object for null, the old mistake from the table.
  5. The template string builds a sentence from two values.
  6. The last line shows the decimal rounding error, a string's length and a string method.

Expected result

string number boolean undefined object
Rahim is 21 years old
0.30000000000000004 5 DHAKA

In the real world

Everything typed in a form arrives as text. A price calculator that forgets to convert will happily show 1050 for 10 plus 50. Money is usually stored as a whole number of the smallest unit, such as cents or paisa, precisely because decimals are approximate.

Common mistakes

  • Changing a const. const x = 1; x = 2; is a TypeError. Use let.
  • Comparing with ==. 0 == "" is true. Use ===.
  • Adding a number to text read from input. "5" + 1 is "51". Convert first: Number("5") + 1.
  • Using a let variable before its line. It exists but cannot be read yet, which is a ReferenceError.
  • Trusting Number(""). An empty string converts to 0, not NaN, so check for empty text first.

Best practices

  • Start with const, and change to let only if you need to.
  • Convert values at the moment you read them, so that the rest of the program can trust them.
  • Round decimals when you display them, not while you are still calculating.

Summary

const and let create variables. Values have types, which typeof reveals. === compares type and value. + joins as soon as one side is a string. Number and String convert on purpose, and Number.isNaN checks whether a conversion failed.

Quick check

1. What is typeof 3.5?
2. What is "5" + 1?
3. Which declaration should you use for a value that never gets a new value?
4. What is 0 === ""?
5. How do you test whether x is NaN?

Key takeaways

  • Use const by default and let only when the value must change.
  • Use === and !==, because == converts types first.
  • Convert input on purpose with Number and String.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.