- Learn
- Computer Science & IT
- Programming
- JavaScript Programming
- JavaScript Variables and Types
JavaScript Variables and Types: Getting Started
let and const, and calculate with numbers, strings and booleans. Learn how JavaScript converts between types, so results like "5" + 2 giving "52" stop being a surprise. Make decisions with comparisons, logical operators, if/else and switch, and find and fix mistakes with the browser console and debugger.BeginnerLesson 1 of 9 in JavaScript Programming Course
What you will learn
- Connect JavaScript to an HTML page, control when the code runs, and use the browser console to run code and see its output.
- Add JavaScript to an HTML pageAttach scripts with the
<script>element, inline or from a separate file, and choose where they go and how they load. - Write statements and use the consoleWrite statements and comments, run code in the browser console, and show output with
console.logand the browser's built-in dialogs.
- Add JavaScript to an HTML page
- Declare variables with clear names, decide between
letandconst, and predict where each variable can be used.- Declare and name variablesCreate variables with
letandconst, give them valid and readable names, and update the ones that change. - Predict scope and the errors let and const reportPredict in which part of the code a variable can be used, and recognize and fix the errors that
letandconstproduce.
- Declare and name variables
- Recognize JavaScript's data types, calculate correctly with numbers, and build and change text with strings and template literals.
- Recognize data types with typeofName JavaScript's data types, tell
nullfromundefined, and check the type of any value withtypeof. - Calculate with numbers and arithmetic operatorsUse the arithmetic and assignment operators, apply operator precedence, round results, and recognize floating-point limits and special number values.
- Create and change stringsWrite string literals, include quotes and special characters, and use the length, index positions and common methods of strings.
- Build text with template literalsInsert values and expressions into text with backtick strings, write multi-line text, and format numbers inside messages.
- Recognize data types with typeof
- Convert values on purpose with
Number(),String()andBoolean(), and predict the automatic conversions JavaScript makes in operators and conditions.- Convert values on purposeTurn text into numbers and other values into strings or booleans, and check whether a conversion worked.
- Predict automatic type coercionPredict the results of operators applied to mixed types, and use truthy and falsy values deliberately.
- Convert values on purpose
- Compare values correctly, combine conditions with logical operators, and choose which code runs with
if,else, the conditional operator andswitch.- Compare valuesUse the comparison operators to produce
trueorfalse, and predict comparisons of strings, mixed types,null,NaNand decimals. - Combine conditions with logical operatorsJoin and reverse conditions with
&&,||and!, use short-circuit evaluation, and supply default values with||and??. - Choose code paths with if, else, the conditional operator and switchWrite
if,else ifandelsechains, choose values with the conditional operator, and handle fixed cases withswitch.
- Compare values
- Read error messages, trace values with console output, and pause code in the browser debugger to see exactly what it does.
- Read error messages and trace values with the consoleTell syntax, runtime and logic errors apart, read what an error message says, and use logged values to find where a result goes wrong.
- Pause and step through code with the debuggerSet breakpoints, step through code line by line, and inspect variable values while the code is paused.
- Read error messages and trace values with the console
JavaScript Variables and Types study guide
1Run a script and see its output
A browser can run a calculation as soon as you load a page, but the code needs a place to live and a way to show its result. Connect a script to HTML, choose when it runs, and use the console to see its messages. Small console experiments will help you learn the language before you change page elements. You will also read the difference between an expression’s value and a message printed by a program.
1.1 Connect JavaScript to HTML
HTML gives a page its structure, CSS controls its appearance, and JavaScript adds behavior. A browser’s JavaScript engine runs the instructions in a script. Unless a decision changes the path, those instructions run from top to bottom.
Put code in the page or in a separate file
An inline script contains JavaScript between opening and closing tags:
<script>
console.log("Hello from the page");
</script>
An external script keeps the JavaScript in a separate .js file. This HTML loads it:
<script src="js/app.js"></script>
The external file contains console.log("Hello from the page"); with no <script> tags. Separating the files keeps HTML readable, lets several pages share code, and lets the browser cache the script. When src is present, code inside the same element is ignored. Use one approach per element, and always write the closing </script> tag: a self-closing <script ... /> does not close the element in HTML.
Choose when the script runs
A classic script with no loading attribute stops HTML parsing while the browser loads and runs it. In <head>, it runs before the later body content has been built. Placing it just before </body> puts the page content ahead of it.
For an external classic script in <head>, defer is a useful default:
<script src="js/app.js" defer></script>
The browser downloads the script while continuing to parse HTML. It runs the script after parsing finishes. Several deferred scripts run in their HTML order, so a second script can use values set by the first.
| Loading choice | When the script runs | Order of several scripts |
|---|---|---|
| Classic, no attribute | When parsing reaches it, after loading | HTML order |
defer | After HTML parsing | HTML order |
async | As soon as its download finishes | Download completion order |
Use async for independent code that does not rely on page readiness or another script. Adding defer to an inline classic script has no effect.
Load a module
<script type="module" src="js/main.js"></script>
A module is deferred by default and runs in strict mode. It can share code through import and export. To load modules in Chrome or Firefox, serve the project with a local development server, such as an editor’s live-server feature. Opening the page at a file:// address causes module-loading restrictions.
Check the connection
Suppose index.html sits beside a js folder containing greet.js. Put console.log("Page ready"); in that script and <script src="js/greet.js" defer></script> in the HTML head. Open the page, then its console: the message is "Page ready".
The relative path starts from the HTML file’s folder. With this layout, src="greet.js" points to the wrong place. A missing-file message means there is no script to execute at that address. If you copied the HTML tags into the JavaScript file, the engine instead reports a syntax error at the markup.
Key Takeaways
- An external script uses
src; its JavaScript file contains code without HTML tags. - A relative script path starts from the HTML file’s folder.
- A deferred external classic script runs after parsing; deferred scripts keep HTML order.
- An async script runs as soon as it is ready, so dependent scripts need another loading choice.
- Modules are deferred by default and use strict mode.
- A script element needs a closing
</script>tag.
1.2 Write instructions and inspect the console
The browser console shows messages, errors, and the results of code you type. Open the console for the page you are testing. In Chrome or Edge, use Ctrl+Shift+J on Windows/Linux or Cmd+Option+J on Mac. In Firefox, use Ctrl+Shift+K or Cmd+Option+K. F12 opens the developer tools as a whole in Chrome and Edge.
Statements and expressions
An expression produces a value: 4 + 5 produces 9. A statement gives an instruction, such as storing that value or printing it:
let total = 4 + 5;
console.log("Total:", total);
The first line runs before the second, which prints "Total: 9". A semicolon ends a statement. JavaScript can insert many omitted semicolons, but line breaks do not always work as separators. End statements with semicolons to make the intended structure clear.
Type 2 + 3 into the console and press Enter to see 5. Use Shift+Enter for a new line without running the entry. If you enter let x = 5;, the console may display undefined as the result of that statement. This does not say that x contains undefined: entering x next shows 5. Likewise, a call to console.log() prints its message and itself returns undefined.
Names and comments
JavaScript is case-sensitive. console.log("Hi"); works, but Console.log("Hi"); refers to a different name and raises ReferenceError. console.Log("Hi"); finds console, but fails with TypeError because there is no callable Log method.
Comments are for readers. The engine skips them:
// Keep the starting value for the next calculation.
let total = 4;
/* A comment can also
continue on another line. */
console.log(total);
Putting // before a statement temporarily switches that line off. A useful comment explains a reason that the code alone does not make clear.
Messages, warnings, and experiments
console.log("Total:", 9); prints its arguments separated by spaces. console.warn() marks a warning; console.error() marks an error message. Printing with console.error() does not itself throw an exception. console.clear() clears the display.
Console entries are experiments, not saved edits. Reloading runs the saved page scripts again. You can inspect top-level variables from classic scripts in the console; a module’s top-level variables stay inside that module.
Simple dialogs and strict mode
alert("Saved!"); shows a message. confirm("Continue?") returns true for OK and false for Cancel. prompt("Quantity?", "1") returns the entered string, or null for Cancel. Typing 12 gives "12", not 12. These dialogs pause interaction while open.
Put "use strict"; at the start of a classic script to make certain mistakes report errors. For example, totl = 5; with no declaration throws ReferenceError in strict mode; in a non-strict classic script it can create an accidental global variable. A module already uses strict mode. Check spelling and declare names before assigning to them.
Key Takeaways
- Console input evaluates expressions, and
console.log()prints messages. - A declaration’s displayed
undefinedis separate from the value stored in its variable. - Names are case-sensitive; comments are skipped during execution.
prompt()returns text ornull, andconfirm()returns a boolean.- Strict mode reports assignments to undeclared names as errors.
2Store values and control where names work
Variables give values names that the rest of your program can use. Choosing const or let tells a reader whether a name will be reassigned. Where you declare a variable also matters: a value created inside a block may be unavailable outside it. Follow a small running total, then trace nested blocks to see which variable each name refers to and why declaration mistakes produce different errors.
2.1 Declare, assign, and update values
A variable is a name that refers to a value. You can declare the name first and assign its value later, or do both in one statement. The assignment operator = stores the right-hand value in the left-hand name.
Choose let or const
let score;
console.log(score); // undefined
score = 10;
score = score + 2;
console.log(score); // 12
let score; declares the variable. Until an assignment gives it another value, it holds undefined. The next assignment stores 10. In score = score + 2;, JavaScript reads the old score, adds 2, then stores 12. This is an update instruction, so it need not make sense as a math equation. Reassignment uses the existing name without writing let again.
A const declaration must include its initial value:
const BOILING_POINT_C = 100;
The declaration const rate; is a syntax error because it lacks an initializer. Trying to assign a new value to BOILING_POINT_C later raises a TypeError.
| Declaration | Needs an initial value? | Can the name be reassigned? |
|---|---|---|
let | No | Yes |
const | Yes | No |
Use const by default. Choose let for a running total, a counter, or a result that later statements will assign. A value calculated from other values can still use const if the program never reassigns that name.
Give the name a clear meaning
Names may contain letters, digits, _, and $; they cannot start with a digit. place1 is valid, but 1stPlace is not. Spaces are forbidden, and a hyphen is read as subtraction, so total-price does not name one variable. Reserved words such as if, return, and class cannot be variable names.
Use camelCase for ordinary names: itemCount, firstName, or priceWithTax. Boolean names such as isLoggedIn and hasDiscount describe a yes-or-no value. Include units when they prevent confusion: distanceKm and durationMin. Fixed values known before the program runs often use UPPER_SNAKE_CASE, such as MAX_LOGIN_ATTEMPTS. Case matters: total and Total are separate names.
Work through a running total
const TAX_RATE = 0.2;
let total = 0;
total = total + 12.5;
total = total + 7.5;
const totalWithTax = total * (1 + TAX_RATE);
console.log(totalWithTax); // 24
The total starts at 0, becomes 12.5, then becomes 20. The multiplier 1 + TAX_RATE is 1.2, so the final amount is 24. Only total needs reassignment. The tax rate and the calculated final amount use const.
If you write let total = 7.5; a second time in the same scope, you are trying to declare a second variable, not update the first. Use total = 7.5; to replace the value.
Recognize older declarations
Older code often uses var. It still works, but its variables belong to a function or script instead of an ordinary nested block. It permits repeated declarations and reads before the declaration produce undefined. Modern let and const catch these mistakes. Keep their rules in mind when reading an older tutorial that uses var.
Key Takeaways
=calculates the right side, then stores its value under the left-hand name.- Use
constby default andletwhen the code will reassign the name. - A
constdeclaration requires an initial value. - Reassign an existing variable without repeating its declaration keyword.
- Descriptive camelCase names can show meaning and units.
2.2 Follow scope and diagnose declaration errors
A block is the code between curly braces, such as an if body. A variable’s scope is the region where its name refers to that variable. Both let and const have block scope, including any nested blocks inside the declaring block.
Keep a result where it is needed
const temperatureC = 31;
let label;
if (temperatureC > 30) {
label = "hot";
} else {
label = "mild";
}
console.log(label); // hot
label is declared outside the branches, so the final line can read it. Each branch assigns the existing variable. If you instead declare const label = "hot"; inside the first branch, that variable cannot be read after the block. With no other label in scope, the final read raises ReferenceError.
A top-level declaration in a classic script has global scope: later code in that script and the page’s other classic scripts can use it. In a module, top-level variables belong to that module. Keep a variable in the smallest scope that needs it to reduce name clashes.
Distinguish shadowing from reassignment
let x = 1;
{
let x = 2;
console.log(x); // 2
}
console.log(x); // 1
The inner declaration creates a separate variable. This is shadowing: within the inner block, x refers to the inner variable. The outer variable remains 1. Removing the inner let would instead assign 2 to the outer variable. Distinct names make this difference easier to read.
Read before initialization
A block-scoped binding covers its whole block, but it cannot be accessed before the declaration initializes it. The region before initialization is the temporal dead zone:
console.log(price);
let price = 5;
This raises ReferenceError: Cannot access 'price' before initialization. The name exists in the scope but is not ready. By comparison, price is not defined means no binding with that name can be found there. An inner declaration also shadows an outer name before the inner declaration line; the outer value cannot bypass the inner variable’s temporal dead zone.
Match each error to a fix
| Problem | Error type | Fix |
|---|---|---|
const rate; | SyntaxError | Supply an initial value |
A second let total in one scope | SyntaxError | Assign without another let |
| Reading before initialization | ReferenceError | Initialize before the read |
| Reading an unknown or out-of-scope name | ReferenceError | Correct the name or move its declaration |
Reassigning a const | TypeError | Use let if reassignment is needed |
Syntax errors prevent that script from starting. A runtime error stops the current execution when it reaches the failing statement. Chrome allows another let declaration in a separate console entry for convenience; this does not make duplicate declarations valid in a script.
Const fixes the reference
Primitive values such as numbers and strings cannot change in place. An object’s contents can change even when its name uses const:
const settings = { theme: "dark" };
settings.theme = "light"; // allowed
The name still refers to the same object. Assigning settings = {}; tries to replace that reference and raises TypeError.
Key Takeaways
letandconstnames are scoped to their containing block.- Declare a shared result before the branches that assign it.
- Shadowing creates a separate variable; reassignment changes the existing one.
- A temporal-dead-zone read fails even though the binding exists in that scope.
- Duplicate declarations are syntax errors, while reassignment of a
constis a runtimeTypeError. - A
constobject can have its contents changed without reassigning the name.
3Calculate with values and build text
A value’s type helps explain what an operation will do. Numbers support calculations, strings hold text, and booleans hold true or false. Learn to inspect those types, control arithmetic order, and store the results of string methods. Template literals then let you combine values into readable messages. Exact console output will show where text, numbers, rounding, and formatting behave differently.
3.1 Identify the type of a value
The values 7, "7", and true have different types. They may appear in similar places on a page, but JavaScript applies different rules to each. A type describes the value currently held, not a permanent restriction on its variable.
Start with the main three types
A number represents whole and decimal numeric values: 42, -7, and 3.75 all have the same type. Scientific notation is also numeric: 1e3 means 1000. A string holds text inside quotes, so "42" is text even though its characters are digits. A boolean is exactly true or false, without quotes. Comparisons produce booleans that a program can use to make decisions.
Use typeof to inspect a value. It returns a string naming the type:
console.log(typeof 7); // number
console.log(typeof "7"); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
The comments show the printed words; the results themselves are strings such as "number".
Recognize missing values
let city;
let middleName = null;
console.log(city); // undefined
console.log(middleName); // null
undefined commonly means JavaScript has not been given a value, as with an uninitialized let. null is commonly assigned deliberately to mean "empty" or "no value". Test for a deliberately empty value with middleName === null.
Do not use typeof value === "object" as a null test. typeof null gives "object" because of a historical language behavior, even though null is a primitive value.
Know the complete type list
JavaScript has seven primitive types: number, string, boolean, undefined, null, bigint, and symbol. The eighth type is object, used for structured values. Functions are objects that can be called, although typeof reports "function" for them.
A bigint is a whole number written with a final n, such as 9007199254740993n. It supports exact large whole numbers. Do not mix a bigint and a number in arithmetic: 1n + 2 throws TypeError. A symbol is a unique identifier; typeof Symbol("id") gives "symbol". typeof 42n gives "bigint".
NaN is another special result to recognize: despite its name, "not a number," typeof NaN is "number". It is a numeric value that marks an invalid numeric result. Its name alone does not identify a separate type.
Trace a changing variable
let data = 42;
console.log(typeof data); // number
data = "forty-two";
console.log(typeof data); // string
This is dynamic typing. Reassignment can replace a number with a string. That flexibility makes it useful to log both the value and its type when a result is surprising:
const input = "7";
console.log(input, typeof input); // 7 string
console.log(input + 1); // 71
console.log(7 + 1); // 8
The first addition joins text; the second adds numbers. Primitive values cannot change in place: an operation creates a new value. Updating a variable changes which value it refers to.
Key Takeaways
- Values have types; a
letvariable can hold different types after reassignment. typeofreturns a string naming a value’s type.undefinedoften means no value was assigned;nullcommonly marks a deliberate absence.typeof nullis"object", andtypeof NaNis"number".
3.2 Control arithmetic and numeric results
JavaScript uses one ordinary number type for whole and decimal values. Division keeps a fractional part: 10 / 4 gives 2.5. The operator you choose and the order in which it runs both affect the result.
Calculate in the intended order
| Operator | Meaning | Example |
|---|---|---|
+, - | Add, subtract | 8 - 3 gives 5 |
*, / | Multiply, divide | 7 / 2 gives 3.5 |
% | Remainder | 17 % 5 gives 2 |
** | Power | 2 ** 3 gives 8 |
Powers run before multiplication, division, and remainder; those run before addition and subtraction. Equal-level operators run left to right, except powers associate right to left: 2 ** 3 ** 2 is 2 ** 9, or 512. Parentheses override that order: 2 + 3 * 4 gives 14, but (2 + 3) * 4 gives 20.
For the average of 72, 85, and 90, add the whole group before dividing:
const average = (72 + 85 + 90) / 3;
console.log(average); // 82.33333333333333
Without parentheses, 72 + 85 + 90 / 3 divides only 90 and gives 187.
Separate whole units and remainders
Math.trunc(7 / 2) drops the fraction and gives 3. For a positive length of 245 cm, Math.floor(245 / 100) gives 2 meters, and 245 % 100 gives 45 remaining centimeters. Similarly, 3725 seconds gives 1 hour with Math.floor(3725 / 3600), 2 minutes with Math.floor((3725 % 3600) / 60), and 5 seconds with 3725 % 60. For an integer, n % 2 === 0 tests evenness. A remainder has the sign of the left operand: -7 % 3 gives -1.
Update a number
x += 5 means x = x + 5. The operators -=, *=, /=, %=, and **= follow the same pattern. Starting at 10, the updates += 5, *= 2, -= 4, then /= 2 give 15, 30, 26, then 13.
++ increases by one and -- decreases by one. With let a = 5; let b = a++;, a becomes 6 but b receives 5: postfix returns the old value. With let b = ++a;, starting again at a = 5, both become 6. An update on its own line avoids relying on that expression result.
Round and format deliberately
| Tool | Result rule | Example |
|---|---|---|
Math.round() | Nearest integer; halves toward positive infinity | Math.round(-2.5) gives -2 |
Math.floor() | Down toward negative infinity | Math.floor(-2.5) gives -3 |
Math.ceil() | Up toward positive infinity | Math.ceil(2.1) gives 3 |
Math.trunc() | Drop the fraction toward zero | Math.trunc(-2.7) gives -2 |
Math.round(13.456 * 100) / 100 gives the number 13.46. By contrast, (3.14159).toFixed(2) gives the string "3.14", and (19.999).toFixed(2) gives "20.00". Format at the end: adding a number to a formatted string joins text.
Recognize numeric limits
Numbers use 64-bit binary floating point. Most decimal fractions are approximate, so 0.1 + 0.2 is 0.30000000000000004. Round for display, compare with a suitable small tolerance, or calculate in whole units such as cents or millimeters.
Some invalid operations return a value instead of throwing: 5 / 0 is Infinity, -5 / 0 is -Infinity, and 0 / 0 or "abc" * 2 is NaN. Most arithmetic with NaN stays NaN; NaN ** 0 is an exception and gives 1.
Every integer through Number.MAX_SAFE_INTEGER, 9007199254740991, is exact. Beyond it, only some integers can be represented: 9007199254740992 + 1 still gives 9007199254740992. Bigints support larger exact integers.
Key Takeaways
- Parentheses can make a whole sum the input to division.
%gives a remainder; division alone keeps the fraction.- Postfix increment returns the old value; prefix increment returns the new one.
- Floor, ceil, round, and trunc differ for negative values.
toFixed()produces text for display.- Decimal arithmetic can be approximate, even for simple-looking inputs.
NaNand infinities are special values of the number type.
3.3 Read, search, and transform text
A string stores text between matching single quotes, double quotes, or backticks. For plain text, all three can represent the same value. Quotes mark where the text begins and ends; they are not part of that value.
Quotes, escapes, and joining
Use the other quote style to include a quote: "It's late". An escape uses a backslash, as in 'It\'s late'. \n represents a line break, \t a tab, and \\ a backslash. The escape \n occupies one string position, even though it takes two typed symbols to write. "It's".length is 4; "Line 1\nLine 2".length is 13.
The + operator concatenates strings. "Hello" + " " + "world" gives "Hello world"; no space is inserted unless one of the pieces contains it. With let msg = "Hi"; msg += " there";, the updated value is "Hi there".
Positions start at zero
const language = "JavaScript";
console.log(language.length); // 10
console.log(language[0]); // J
console.log(language[4]); // S
console.log(language[9]); // t
console.log(language.at(-1)); // t
console.log(language[10]); // undefined
The final index is length - 1. A negative argument to at() counts from the end. length is a property, not a method: language.length() raises TypeError. More precisely, string positions and length use UTF-16 code units, the units JavaScript uses to store text. These ordinary English letters each occupy one unit; some symbols and emoji occupy more.
Save the new string
Strings are immutable: their contents cannot be edited in place. Assigning word[0] = "b" when word is "cat" does not create "bat"; in strict mode it throws. Methods that transform text return a new string:
let name = "ana";
name.toUpperCase();
console.log(name); // ana
name = name.toUpperCase();
console.log(name); // ANA
Calling the method is not enough to keep its result. Writing name.toUpperCase without parentheses does not call it at all.
Pick the right text operation
toLowerCase() and toUpperCase() change case; trim() removes whitespace at both ends. Chaining applies each method to the preceding result: " Ana@Example.com ".trim().toLowerCase() gives "ana@example.com".
includes(), startsWith(), and endsWith() return booleans. For example, "report.pdf".endsWith(".pdf") gives true. indexOf() gives the first matching position or -1: "JavaScript".indexOf("S") gives 4, but searching for "s" gives -1. Searches are case-sensitive. "JavaScript".includes("script") is false; convert to lowercase before that search to get true.
slice(start, end) returns text from the start index up to, excluding, the end index. "JavaScript".slice(0, 4) gives "Java"; .slice(4) and .slice(-6) give "Script".
"a-b-c".replace("-", "+") gives "a+b-c"; replaceAll() with the same arguments gives "a+b+c". "ab".repeat(3) gives "ababab", and "5".padStart(3, "0") gives "005". For const city = "paris";, city[0].toUpperCase() + city.slice(1) produces "Paris" by joining an uppercase first letter to the unchanged remainder.
Key Takeaways
- Strings need matching quotes, and concatenation adds no spaces on its own.
- The first index is zero and the final ordinary-letter index is
length - 1. lengthis a property; methods are called with parentheses.- Transforming methods produce new strings, so save their results.
- String searches distinguish uppercase and lowercase.
slice()excludes its end index.
3.4 Insert values into readable messages
A template literal puts text between backticks. Inside it, ${...} marks a placeholder whose expression will be evaluated and inserted into the text. This is useful when a message combines several values with punctuation, spaces, or calculations.
Read a placeholder as an expression
const name = "Ana";
const greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, Ana!
The engine reads name, obtains "Ana", and places it between the greeting and the exclamation point. The backticks and placeholder symbols describe the string; they do not appear in the resulting message.
With concatenation, the same idea is "Hello, " + name + "!". A longer message such as "Hello, " + name + "! You have " + count + " new messages." requires several separately quoted pieces. A template keeps the whole sentence together: `Hello, ${name}! You have ${count} new messages.`. Spaces still have to be typed where you want them.
Calculate, then format inside the gap
const name = "Ana";
const tickets = 3;
const price = 4.5;
const receipt = `${name} bought ${tickets} tickets for ${(tickets * price).toFixed(2)} in total.`;
console.log(receipt);
The output is "Ana bought 3 tickets for 13.50 in total." First, tickets * price produces 13.5. Parentheses make that whole product the receiver of .toFixed(2), which produces "13.50". The placeholder inserts that text into the sentence. The numeric price and tickets variables stay unchanged.
Without formatting, a placeholder shows the number’s ordinary text form. `${0.1 + 0.2}` gives "0.30000000000000004". Formatting inside it, `${(0.1 + 0.2).toFixed(2)}`, gives "0.30".
Expressions fit; statements do not
A placeholder can contain a value, a calculation, a method call, or an expression that chooses a value. With birthYear = 1990, `You turn ${2026 - birthYear} this year.` gives "You turn 36 this year."
The conditional operator can select singular or plural text:
const count = 1;
console.log(`You have ${count} ${count === 1 ? "item" : "items"}`);
// You have 1 item
The comparison chooses one string to insert. An if statement cannot replace that expression inside ${...} because a placeholder needs an expression that produces a value.
Keep the exact punctuation
Only backticks activate placeholders. With const n = 5;, "n + 1 = ${n + 1}" is ordinary text and leaves ${n + 1} unchanged. The template `n + 1 = ${n + 1}` gives "n + 1 = 6". A backtick is a different character from a single quote.
Line breaks typed inside backticks become line breaks in the resulting string. Indentation spaces also become part of it. Missing values are inserted as text: `${undefined}` gives "undefined", while `${null}` gives "null". If a message unexpectedly contains "undefined," inspect the inserted variable and where it was assigned.
Key Takeaways
- Backticks activate
${...}placeholders. - A placeholder evaluates an expression and inserts its text form.
- Format a calculated number inside its placeholder when the message needs fixed decimals.
- Quoted strings leave placeholder symbols unchanged.
- Template line breaks and indentation become part of the string.
4Convert input and predict automatic changes
Text entered by a user often needs to become a number before a calculation can work. JavaScript also converts values on its own, and its addition rule can turn an intended total into joined text. Learn to choose a conversion, check for missing or invalid input, and trace an expression in evaluation order. The same values will then make sense when they are used as conditions instead of numbers.
4.1 Convert input without losing its meaning
Explicit conversion means you write the conversion yourself, using a tool such as Number(), String(), or Boolean(). It makes the intended type visible at the point where a value enters the calculation.
Choose a numeric conversion
Number() reads the whole text as a number, ignoring surrounding whitespace. Number("1.5") gives 1.5, and Number(" 12 ") gives 12. Number("12px") gives NaN because the whole string is not numeric. Code uses a decimal point: Number("1,5") also gives NaN.
parseInt() and parseFloat() read a numeric beginning and stop when the text no longer fits. parseInt("12px", 10) gives 12; parseFloat("3.75 kg") gives 3.75. The integer parser stops at the decimal point, so parseInt("0.5", 10) gives 0. parseInt("abc", 10) gives NaN because there is no numeric beginning. Pass a base to parseInt(): parseInt("08", 10) gives 8, while parseInt("ff", 16) reads hexadecimal and gives 255.
Unary plus also converts ordinary numeric text: +"42" gives 42.
Keep missing input separate from zero
A prompt returns a string or null. Cancel returns null, and accepting an empty box returns "". Both become zero under Number(), as does whitespace-only text. Check for absence before converting:
const input = prompt("Enter a quantity:");
if (input === null || input.trim() === "") {
console.log("No quantity entered.");
} else {
const quantity = Number(input);
if (Number.isNaN(quantity)) {
console.log("Please type a number.");
} else {
console.log(quantity + 1);
}
}
The || skips the trim() call when input is null. Typing "12" reaches the numeric calculation and prints 13. Typing "12px" reaches the invalid-number message. Typing "0" is a valid answer and prints 1.
Use Number.isNaN(value) to test for an actual NaN value. value === NaN never succeeds. The older global isNaN() first converts its argument: isNaN("hello") is true, but Number.isNaN("hello") is false because that value is still a string.
Convert to text or a boolean
String(42) gives "42", String(true) gives "true", and String(null) gives "null". (42).toString() also produces "42", but calling .toString() on null or undefined raises TypeError. String() handles both.
Boolean() returns false for false, 0, -0, 0n, "", null, undefined, and NaN; these are falsy. Browsers also have the legacy falsy object document.all. Other values are truthy. In particular, "0", "false", and a single-space string are all truthy. !!value gives the same boolean conversion.
For two prompt answers "12" and "30", a + b produces "1230". Convert both inputs first: Number(a) + Number(b) gives 42.
Key Takeaways
Number()expects the whole string to be numeric; parsers can read a numeric prefix.- Check Cancel and blank input before numeric conversion so they do not become zero.
- Use
Number.isNaN()to detect an invalid numeric result. - Nonempty strings such as
"false"are truthy. String()can convertnullandundefinedsafely.
4.2 Predict coercion one operation at a time
Coercion is automatic type conversion inside an operation. Its rules depend on the operator. A calculation that appears to work can still contain a text value that causes a later step to fail.
Follow the addition rule
For ordinary number, string, boolean, null, and undefined operands, + joins text if either operand is a string. Otherwise it performs numeric conversion and addition. "5" + 2 gives "52", and 2 + "5" gives "25".
Evaluate a chain from left to right:
console.log(1 + 2 + "3"); // 33
console.log("3" + 1 + 2); // 312
In the first expression, two numbers add to 3; adding "3" then joins the two text forms into "33". In the second, the first operation already produces "31", so the final operation appends another digit. Parentheses can change which operation happens first: "3" + (1 + 2) gives "33".
Other arithmetic expects numbers
Subtraction, multiplication, division, remainder, and powers convert numeric strings to numbers. "5" - 2 gives 3, "5" * "2" gives 10, and "10" / "4" gives 2.5. A string such as "abc" cannot become a valid number, so "abc" * 2 gives NaN. Bigints have separate arithmetic rules; mixing one with a number raises TypeError.
This difference can hide a bug:
const price = "20";
console.log(price * 3); // 60
console.log(price + 5); // 205
Multiplication converts the price, but it does not change the variable. The later addition still sees a string. Convert once where input arrives, then keep working with the numeric result.
Trace small automatic conversions
In numeric arithmetic, true becomes 1, false becomes 0, and null becomes 0. Thus true + true gives 2, while null + 1 gives 1. undefined becomes NaN, so undefined + 1 is NaN. Unary plus and minus convert numeric strings: +"42" gives 42, -"5" gives -5, and +"" gives 0.
++ always requests a numeric update, but += follows the addition rule:
let count = "5";
count++;
console.log(count, typeof count); // 6 number
let label = "5";
label += 1;
console.log(label, typeof label); // 51 string
Conditions apply a different conversion
An if condition judges a value as truthy or falsy. "0" is a nonempty string and passes; numeric 0 is falsy and skips the block. If zero is a valid quantity, a truthiness check alone cannot tell zero from a missing answer. For a value represented by a number or null, quantity !== null tests for absence explicitly.
Equality also offers two behaviors: "7" == 7 is true after coercion, but "7" === 7 is false because strict equality preserves the type distinction. Use strict equality for ordinary comparisons.
When a result is joined text or NaN, log each input beside typeof input. Find the first incorrect type and correct the conversion there. Turning "205" into a number at the end would give 205, not the intended sum 25.
Key Takeaways
- For ordinary primitive values, a string operand makes
+concatenate. - Trace
+chains from left to right, respecting parentheses. - Other arithmetic converts numeric strings without changing the original variables.
++converts to a number, while+=can append text.- Truthiness is different from validity: zero can be a valid input.
5Compare values and choose a path
Decisions turn values into actions: a comparison can decide whether a measurement is in range, a message is missing, or a fixed choice matches. Combine tests carefully, then use them to choose a value or a block of code. The order of branches and the types being compared affect the result. Trace each condition with concrete inputs, including zero, an empty string, and a value exactly at a threshold.
5.1 Compare values without hidden assumptions
A comparison produces a boolean. 7 > 3 is true, 5 >= 5 includes equality and is true, and 4 < 2 is false. Store a result such as const isAdult = age >= 18;, or use it directly in a condition.
Prefer strict equality
=== compares without converting types. Two ordinary primitive values must have the same type and matching values: 7 === 7 is true, while "7" === 7 is false. !== reverses strict equality, so "7" !== 7 is true.
Loose equality, ==, can convert operands. "7" == 7, 0 == "", and "0" == false are all true. Its special missing-value rule makes null == undefined true but null == 0 false. != reverses loose equality. Prefer === and !==; a deliberate value == null can test for either null or undefined.
Tell text ordering from numeric ordering
Two strings compare from left to right using their UTF-16 code values. For ordinary English words in the same case, "apple" < "banana" is true. A shorter matching prefix comes first: "apple" < "apples" is true. Among the unaccented English letters, uppercase letters come before lowercase letters, so "Zebra" < "apple" is true. Converting both strings with toLowerCase() removes that case difference in simple English-letter comparisons.
Digit strings also follow text order:
console.log("10" < "9"); // true
console.log("10" < 9); // false
In the first comparison, the character "1" comes before "9". In the second, one operand is numeric, so the text becomes the number 10. Convert numeric input deliberately before comparing its size. "abc" < 5 and "abc" > 5 both give false because the numeric conversion produces NaN.
Handle missing and invalid numbers first
NaN does not equal itself: both NaN === NaN and NaN == NaN are false. Use Number.isNaN() to recognize it.
Relational comparisons convert null to zero, so null >= 0 is true but null > 0 is false. Equality has a different rule, so null == 0 remains false. undefined becomes NaN in relational comparisons, so undefined > 0 and undefined < 0 are false; undefined == 0 is false too. Check for a missing value before treating it as a measurement.
Compare decimals and ranges
Binary rounding means 0.1 + 0.2 === 0.3 is false. For these small values, a tolerance test works:
const closeEnough = Math.abs((0.1 + 0.2) - 0.3) < 0.000001;
console.log(closeEnough); // true
Math.abs() removes the sign of the difference. Choose a tolerance suited to the size and precision of the values, or calculate in whole units such as millimeters.
Do not chain range tests as in math. With x = 50, 0 < x < 10 first produces true, then compares that boolean as 1 < 10, yielding true. Likewise, 3 > 2 > 1 becomes true > 1, or 1 > 1, which is false. Write both comparisons in full: x > 0 && x < 10.
Key Takeaways
- Strict equality checks types without coercion.
- Two digit strings compare as text; convert them to compare numeric size.
- Check missing values and
NaNbefore numeric comparisons. - Decimal results may need a tolerance instead of exact equality.
- Join two range comparisons with
&&; do not chain them.
5.2 Combine tests and choose defaults
Logical operators let a condition express several requirements. With boolean operands, && means AND, || means OR, and ! means NOT. Their evaluation order also lets you guard an operation that would fail on a missing value.
Express every requirement
const temperatureC = 25;
const inRange = temperatureC >= 18 && temperatureC <= 30;
const outside = temperatureC < 18 || temperatureC > 30;
inRange is true because both limits hold. outside is false because neither outside test holds. OR includes the case where both sides are true; it is not "one but never both."
Write each comparison in full. color === "red" || "green" does not test for either color. With color = "blue", the first comparison is false, but the nonempty string "green" is truthy. The intended test is color === "red" || color === "green".
Group the condition you mean
NOT binds before AND, and AND before OR. Thus true || false && false is true, but (true || false) && false is false.
Suppose access requires a login and either the admin or owner role. Write loggedIn && (isAdmin || isOwner). Without parentheses, loggedIn && isAdmin || isOwner lets isOwner make the whole expression true even with loggedIn = false. Parentheses keep the login requirement attached to both roles.
Reversing a compound condition also changes the connector. !(a && b) has the same truth value as !a || !b; !(a || b) matches !a && !b. For a temperature outside the inclusive interval, reversing the two inside tests changes >= to <, <= to >, and AND to OR.
Stop when the result is known
AND stops at the first falsy operand; OR stops at the first truthy operand. This is short-circuit evaluation. The skipped operand is not evaluated:
const input = null;
const hasText = input !== null && input.trim() !== "";
console.log(hasText); // false
The first test is false, so trim() is never called on null. Reversing those two tests would try the unsafe operation first.
These operators return an operand, not necessarily a boolean. "" || "Guest" returns "Guest"; "Sam" || "Guest" returns "Sam". "Ana" && "ok" returns "ok", and null && "x" returns null. A surrounding if then tests the returned value’s truthiness.
Preserve meaningful falsy values
| Expression | When the fallback replaces the input |
|---|---|
| `value | |
value ?? fallback | Only for null or undefined |
With quantity = 0, quantity || 1 gives 1, but quantity ?? 1 preserves 0. With nickname = "", nickname || "Anonymous" gives the fallback, while nickname ?? "Anonymous" preserves the empty string. Use ?? when those values are meaningful.
Parenthesize when mixing ?? with AND or OR: a || b ?? c is a syntax error, while (a || b) ?? c has an explicit grouping. NOT first converts to a boolean, then reverses it: !0 is true and !"0" is false. Double NOT, !!value, gives a plain boolean.
Key Takeaways
- AND requires both tests; OR requires at least one.
- Parentheses keep shared requirements attached to every allowed case.
- Short-circuiting skips an operand once the result is settled.
&&and||return operand values, which may be non-booleans.??replaces onlynullandundefined, preserving zero and empty text.- Mixing
??directly with AND or OR requires parentheses.
5.3 Choose branches, values, and fixed cases
An if statement runs a block when its condition is truthy. An else runs when that condition is falsy. Use braces to show exactly which statements belong to each branch.
Order a chain of decisions
An else if chain checks from top to bottom. The first passing condition wins, and all later branches are skipped:
const score = 85;
let grade;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70) {
grade = "C";
} else {
grade = "F";
}
The first comparison fails; the second passes, so grade becomes "B". Testing score >= 70 first would catch even a score of 95 and assign "C". For overlapping minimum thresholds, put the highest first. The shared grade variable is declared outside the branches so later code can read it.
A compound condition can keep a short decision readable. Shipping is free for an order total of at least 50 or for a member; otherwise it costs 4.95:
const orderTotal = 45;
const isMember = false;
let shipping;
if (orderTotal >= 50 || isMember) {
shipping = 0;
} else {
shipping = 4.95;
}
console.log(`To pay: ${orderTotal + shipping}`);
// To pay: 49.95
Two nested conditions without else branches can often be joined with AND: if (isLoggedIn) { if (isAdmin) { ... } } runs its innermost code under the same boolean conditions as if (isLoggedIn && isAdmin) { ... }.
Avoid punctuation that changes the path
Without braces, only the next statement belongs to an if; indentation cannot add another statement to it. A semicolon immediately after the condition creates an empty statement: if (x > 5); { ... } leaves the following block running regardless of the condition.
if (x = 5) assigns 5 and then tests its truthiness. It changes x and passes because 5 is truthy. To compare, use if (x === 5).
Choose a value with a conditional expression
The conditional, or ternary, operator returns one of two values:
const age = 17;
const status = age >= 18 ? "adult" : "minor";
console.log(status); // minor
The form is condition ? valueIfTrue : valueIfFalse. Use it for a short choice inside an assignment or template literal. Use if/else for branches of statements. Deeply nested conditional expressions make the choices hard to follow.
Match fixed choices with switch
const day = "Sat";
let kind;
switch (day) {
case "Sat":
case "Sun":
kind = "weekend";
break;
default:
kind = "weekday";
}
switch compares the value strictly with its case labels. Both weekend labels reach the same assignment. break exits the switch; default handles a value with no matching case. switch ("2") does not match case 2: because the types differ.
After a match, execution continues through later cases until a break or the end. This fall-through can be deliberate, as in stacked labels, or accidental. If case 2 adds a word and lacks a break before case 3 adds another, both additions run. A case label is an entry point, not a fresh condition tested after every statement.
Key Takeaways
- An
else ifchain runs its first passing branch only. - Declare a result outside the branches when later statements need it.
- Use braces, and do not put a semicolon directly after an
ifcondition. =assigns a value;===compares values.- The conditional operator chooses a value.
switchmatches strictly and needsbreakto stop fall-through.
6Find the first wrong step
An error message can point directly to a mistake, but a program can also run successfully and produce the wrong result. Read the console’s type, message, and location, then trace the values that matter. When logs leave too much to guess, pause execution and step through it. A small, repeatable debugging routine helps you test one cause at a time and verify the correction in the saved program.
6.1 Read errors and trace incorrect results
A program can fail before it starts, stop during execution, or finish with the wrong result. Identify which happened before changing code. The console gives evidence about errors, while labeled logs reveal values in code that runs.
Separate three kinds of problem
| Kind | What happens | Example |
|---|---|---|
| Syntax error | The script cannot be parsed; none of that script runs | An unclosed parenthesis |
| Runtime error | Execution reaches a statement that throws; earlier statements have run | Reading an unknown name |
| Logic error | The code runs but the result is wrong | Dividing only the last part of a sum |
A syntax error in one script does not undo a different script that already ran. An unhandled runtime exception stops the current execution at the failing statement.
Read the complete message
A console entry such as Uncaught ReferenceError: totl is not defined gives the error type and the failing name. "Uncaught" means the exception was not handled. A location such as app.js:2 points to the file and line; clicking it opens that code.
let total = 0;
total = totl + 5;
console.log(total);
Line 1 runs. On line 2, JavaScript cannot read totl, so it never completes that assignment or reaches the final log. Correcting the misspelling to total makes the script print 5.
Common syntax messages mention a missing ), an unexpected token, or an invalid token. In console.log("hi";, the closing parenthesis is absent. In if (x > 3 {, the condition lacks its closing parenthesis. The reported line is where the engine noticed the problem; inspect just above it too for an unclosed quote or delimiter.
Use the type to narrow the cause
A ReferenceError points to a name that cannot be accessed: a typo, a scope problem, or a read before initialization. A TypeError means the operation does not fit the value, such as "abc".length(), null.trim(), or a reassignment to a const. A RangeError can come from an unsupported argument, such as (1.5).toFixed(101).
Error wording can differ by browser. The type and the value involved are more useful than memorizing the whole sentence. Fix the first relevant error and run again, because later messages may follow from the same cause.
Trace a logic error
For a wrong average, log the sum and result separately:
const sum = 72 + 85 + 90;
const average = 72 + 85 + 90 / 3;
console.log("sum:", sum); // 247
console.log("average:", average); // 187
The correct sum narrows the fault to the division step. Change the calculation to sum / 3, which gives 82.33333333333333. When addition unexpectedly joins digits, also log types: console.log("price:", price, typeof price);. Find the first value that differs from your expectation.
Use console.warn() or console.error() to make your own diagnostic messages stand out. Check the console level filters if a log seems absent. A 404 means a resource was not found, so check the script path; other loading failures need their full message. A missing startup log can also reflect a filter or a syntax error.
Reproduce the problem, read the first error, test one likely cause with a small change or log, then rerun and check the expected result. Remove temporary logs when the bug is fixed.
Key Takeaways
- Syntax, runtime, and logic errors need different kinds of evidence.
- Read the error type, full message, and location.
- A reported syntax-error line can follow the actual missing delimiter.
- Log values and types to find the first incorrect step.
- Check loading failures and console filters when expected output is absent.
6.2 Pause execution and inspect live values
A debugger lets you pause a running script and inspect the values at that exact moment. Use the Sources panel in Chrome or Edge, or the Debugger panel in Firefox. This is especially helpful when a wrong result depends on several earlier operations.
Pause before the line runs
Open the script in Sources and click a line number to set a breakpoint. Execution pauses before that line runs. If the code runs during page loading, reload the page after setting the breakpoint. Merely setting one does not rerun code that already finished.
You can also write debugger; in the script. With an active debugger it pauses execution; without one it has no effect. Remove this statement before publishing the code.
Choose the next action
| Chrome control | Shortcut | Effect |
|---|---|---|
| Resume | F8 | Continue to the next breakpoint or the end |
| Step over | F10 | Run the current statement without entering a called function |
| Step into | F11 | Enter a called function when available to the debugger |
| Step out | Shift+F11 | Finish the current function and pause back in its caller |
Some built-in calls have no JavaScript source you can step into. Step over is useful when you want the call’s result without following its internal work.
While paused, hover over a name to inspect it, read local values in Scope, or add an expression to Watch. Watch entries such as typeof price and total > 100 are reevaluated as you step. The console can also evaluate expressions using the paused scope.
Inspect a misleading total
Free shipping should start at 50, but this code grants it for a subtotal of 45 plus 4 shipping:
const subtotal = "45";
const shipping = 4;
const total = subtotal + shipping;
if (total >= 50) {
console.log("Free shipping");
}
Set a breakpoint on the if line and reload. The assignment has already run. Scope shows subtotal as the string "45" and total as "454". A Watch entry typeof total reports "string". The comparison converts "454" to a number, so total >= 50 passes.
The fault is in the addition, before the comparison. Change the saved calculation to const total = Number(subtotal) + shipping;. Reload again. The total is now the number 49, and the condition is false. If you pause on the assignment instead, it has not run yet: step over it before inspecting the initialized total.
Pause only where useful
A conditional breakpoint pauses only when its expression is true, such as total > 100. Right-click the line number to add one. A logpoint prints a message each time its line runs without pausing or editing the script. Exception breakpoints pause where an exception is thrown, so you can inspect values at the failure.
Stepping through an else if chain reveals which branch is reached and which earlier condition prevents later checks. Use logs for a few known values and the debugger when order or several live values matter. Make the final correction in the saved project code: an experimental change in the browser is not a lasting edit to your project. Rerun the original failing case and check the corrected result.
Key Takeaways
- A line breakpoint pauses before its statement runs; reload code that runs at page load.
- Step over runs a statement; Step into and Step out follow function calls.
- Scope and Watch reveal live values and expressions while paused.
- Inspect a wrong type before the operation that uses it.
- A conditional breakpoint filters pauses; a logpoint prints without pausing.
- Save the correction in the project and rerun the failing case.
JavaScript Variables and Types examples
1Load a script and read its first messages
13 steps
- 1IntroductionGive the code a place to run
A browser reads HTML to build the page and runs JavaScript to carry out instructions. To see a first result, you need a connected script and an open console. We will follow one small page from its file layout to its printed message, then use console entries to distinguish stored values from the results of statements.
- 2ExplanationChoose inline or external code
An inline script holds code between its tags. An external script uses
srcto load a separate JavaScript file:<script src="js/greet.js"></script>The external file holds JavaScript without HTML tags. Code inside this same element would be ignored because
srcis present. Keep the closing</script>tag; HTML does not treat this element as self-closing. - 3ExampleMatch the path to the folders
Put
index.htmlbeside a folder namedjs, withgreet.jsinside that folder. The page’ssrc="js/greet.js"starts at the HTML folder and entersjs.In the JavaScript file, write:
console.log("Page ready");Save both files. A path of
greet.jswould look beside the HTML file instead of inside its child folder, so it would not find this script. - 4ExplanationRun after the page is parsed
Add
deferto the external classic script in the head:<script src="js/greet.js" defer></script>The download happens alongside HTML parsing. Execution waits until parsing is complete. Several deferred classic scripts keep their HTML order, which matters when one uses a value established by another. Adding
deferto inline classic code does not delay it. - 5ChallengeKeep dependent scripts in order
A page has
setup.jsfollowed bydisplay.jsin its head. The second script uses a value from the first, and both need parsed page content. Wouldasyncon both preserve these requirements? What loading choice would?---reveal---
No. Async scripts execute when each download finishes, so their order and page readiness are not guaranteed. Use
deferon both external classic scripts, keeping setup first in the HTML. - 6ConnectionRecognize a module script
A script loaded with
type="module"is deferred by default, uses strict mode, and keeps its top-level names inside the module. Modules can share code through import and export. Load module pages through a local development server in Chrome or Firefox; directly opening a file address runs into module-loading restrictions. These are different loading rules from an ordinary classic script. - 7TipOpen the console for this page
In Chrome or Edge, open the console with
Ctrl+Shift+Jon Windows/Linux orCmd+Option+Jon Mac. Firefox usesCtrl+Shift+KorCmd+Option+K. Reload the saved page and look for "Page ready". A missing-file error points you back to the path; a syntax error points into code the engine could not parse. Console entries belong to the current page. - 8ExampleSeparate printing from evaluation
Enter these as separate console entries:
let total = 9; total; console.log("Total:", total);The declaration can display
undefinedas its result. Readingtotalstill gives9. The final call prints "Total: 9" and itself returnsundefined. A statement’s displayed result is not necessarily the value stored in the variable or the message printed by that call. - 9ChallengeRead a console declaration
You enter
let count = 6;and seeundefined. Then you entercount + 2. What result should you expect, and did the first display mean the declaration failed?---reveal---
The result is
8. The declaration stored 6 successfully; its own result was undefined. The later expression reads that stored number and adds 2. No reassignment happens, so count itself still holds 6. - 10ExplanationUse exact names and clear notes
JavaScript distinguishes capitalization.
console.log()works;Console.log()looks for a different name. Use//for a one-line comment or/* ... */for a longer one. The engine skips comment text.Start a classic script with
"use strict";to catch undeclared assignments. A typo such astotl = 5;then reports an error instead of creating an accidental global name. - 11ExampleInspect the type of dialog input
Run this practice dialog code:
const input = prompt("Quantity?", "1"); console.log(input, typeof input);Accepting a typed 6 gives
6 string: the digits came back as text. Cancel returns null, while accepting an empty box returns an empty string.confirm()instead returns a boolean, andalert()displays a message. A dialog waits for the response before the following statement runs. - 12ChallengeConnect loading with output
An external classic script loaded with defer contains
console.log("Started"); const answer = prompt("Code?"); console.log(typeof answer);. The user types 42 and accepts. What appears, in order, and would reloading preserve that entered answer automatically?---reveal---
The messages are "Started" and "string". Prompt returns text, even for digits. Reloading reruns the saved script and opens the prompt again; the previous execution’s variable is not a saved project edit.
- 13RecapCheck a first script
For a first script, confirm the relative path, choose the loading behavior, save, and reload. Read the console message separately from the console’s own evaluation result. When a prompt supplies input, inspect its value and type before building a calculation around it. A new console experiment changes the running page, so keep lasting edits in the project.
2Trace declarations, updates, and scope
11 steps
Save this lesson to follow every Walkthrough step by step.
- 1IntroductionFollow one value through a program
- 2ExplanationChoose declarations by reassignment
- 3ExampleRead the old value before storing the new one
- 4ExampleCalculate a final value once
- 5ChallengeChoose the declaration that fits
- 6ExplanationPut a shared result outside its branches
- 7ChallengeSpot shadowing
- 8Key InsightA binding can exist before it is ready
- 9TipRead the error type as evidence
- 10ChallengeRepair the result without hiding it
- 11RecapRead the binding, then the value
3Calculate a total and build its message
18 steps
Save this lesson to follow every Walkthrough step by step.
- 1IntroductionCarry meaning from values to text
- 2ExplanationInspect a value before using it
- 3ChallengePredict a changing type
- 4Key InsightDo not overread a type label
- 5ExampleCalculate before formatting
- 6ExplanationMake the whole sum the numerator
- 7ChallengeFind the complete meters
- 8TipChoose rounding by direction
- 9ConnectionKeep precision separate from display
- 10ExplanationKeep the result of a transformation
- 11ExampleRead indexes and a slice
- 12ChallengeClean first, then check
- 13Key InsightKnow whether a method returns text
- 14ExampleInsert the calculated total
- 15ChallengeChoose the needed quotation marks
- 16ExplanationLet the expression choose a word
- 17ChallengeCombine cleanup and numeric presentation
- 18RecapInspect a message from the inside out
4Accept a quantity without hiding missing input
12 steps
Save this lesson to follow every Walkthrough step by step.
- 1IntroductionSeparate absence from a numeric value
- 2ExampleInspect the raw answer
- 3ExplanationCheck absence before conversion
- 4ExampleReject a failed conversion
- 5ChallengeChoose a parser for the meaning
- 6Key InsightConvert truthiness without reading the word
- 7ExampleNotice a calculation that hides text
- 8ExplanationEvaluate a chain from the left
- 9ChallengeTrace two different updates
- 10TipFix the input before the total
- 11ChallengePreserve zero through the whole path
- 12RecapValidate in the order information is available
5Build a decision that matches its rules
15 steps
Save this lesson to follow every Walkthrough step by step.
- 1IntroductionTurn a rule into a predictable decision
- 2ExplanationKeep types visible in equality
- 3ExampleCompare numbers stored as text
- 4ChallengeIdentify a comparison’s real operands
- 5TipCheck absence and numeric precision
- 6ExplanationMake every requirement explicit
- 7ExampleGroup a shared requirement
- 8ChallengeKeep an empty value when it is valid
- 9Key InsightShort-circuiting controls what is evaluated
- 10ExampleTrace the first passing branch
- 11ChallengeChoose one value or several statements
- 12ExplanationRead switch as an entry point
- 13ChallengePredict the missing break
- 14ChallengeCombine conversion with branch order
- 15RecapTest the rule at its boundaries
6Locate and repair a misleading total
12 steps
Save this lesson to follow every Walkthrough step by step.
- 1IntroductionFind where the result first becomes wrong
- 2ExplanationClassify the failure before changing code
- 3ExampleRead the failing name and location
- 4ChallengeDistinguish parsing from execution
- 5TipLog the first unexpected value
- 6ExampleReproduce the wrong decision
- 7ExplanationPause before the comparison
- 8Key InsightThe later conversion cannot repair addition
- 9ChallengeInspect before and after an assignment
- 10TipChoose the pause that answers the question
- 11ChallengeVerify a type fix through a decision
- 12RecapRetest the saved correction
JavaScript Variables and Types practice questions
Set 1: Run code and follow stored values10 Practice Questions
Question 1 of 10
scripts folder containing start.js. What element loads that file after HTML parsing finishes?Show answerHide answer
scripts folder, and defer delays the external classic script until parsing finishes. async also downloads alongside parsing, but it can execute before parsing is complete. Writing the path as inline text does not load a file.Question 2 of 10
What message does this code print?
// console.log("Old");
console.log("Items:", 6 + 2);
Show answerHide answer
console.log() separates the label and result with a space, producing "Items: 8". Joining the digits into "62" would require string concatenation, but both operands here are numbers.Question 3 of 10
const rate = 0.15; and then executes rate = 0.2;. What happens at the assignment?Show answerHide answer
const binding throws a TypeError when execution reaches it. A missing initializer would instead make the declaration itself a syntax error.Question 4 of 10
What value is printed?
let balance = 14;
balance = balance + 9;
balance = balance - 4;
console.log(balance);
Show answerHide answer
Question 5 of 10
What values are printed, in order?
let level = 4;
{
let level = 9;
console.log(level);
}
console.log(level);
Show answerHide answer
Question 6 of 10
typeof "28" return?Show answerHide answer
"28" a string even though its characters are digits. typeof reports the value’s current type and does not convert the text to a number. The result "number" would describe the unquoted value 28, not the value given here.Question 7 of 10
Show answerHide answer
Question 8 of 10
"catalog".slice(1, 4) return?Show answerHide answer
slice(1, 4) copies positions 1, 2, and 3 and excludes position 4, giving "ata". Including the end position would incorrectly add the next letter and produce "atal".Question 9 of 10
ReferenceError: lenght is not defined. What should you inspect first?Show answerHide answer
lenght is misspelled or unavailable in the current scope. A wrong script path would prevent that file’s startup statement from running, which does not fit the observation.Question 10 of 10
Assume no earlier cost declaration. What is printed before this script stops?
let cost = 8;
{
console.log(cost);
let cost = 12;
}
console.log(cost);
Show answerHide answer
cost binding covers the whole block and shadows the outer one even above its declaration. The first log therefore reads an uninitialized inner binding and throws ReferenceError before printing. It cannot fall back to the outer 8 or read the inner binding as undefined.Set 2: Build text and convert input10 Practice Questions
Save this lesson to see every answer and practice every set.
Question 1 of 10
Number("18px") produce?Show answerHide answer
Save this lesson to see this answer.
Question 2 of 10
"notes.txt".endsWith(".txt") return?Show answerHide answer
Save this lesson to see this answer.
Question 3 of 10
What is printed?
let tag = " mixed ";
tag.trim().toUpperCase();
console.log(tag.length);
Show answerHide answer
Save this lesson to see this answer.
Question 4 of 10
const trays = 4; const massKg = 1.25;, what does `Mass: ${(trays * massKg).toFixed(1)} kg` produce?Show answerHide answer
Save this lesson to see this answer.
Question 5 of 10
const name = "Mira";, what text is stored by const label = "Hello, ${name}";?Show answerHide answer
Save this lesson to see this answer.
Question 6 of 10
Number(input). What value results, and what information has been lost?Show answerHide answer
Save this lesson to see this answer.
Question 7 of 10
6 + 2 + "4"?Show answerHide answer
Save this lesson to see this answer.
Question 8 of 10
const shown = (7.5).toFixed(2);, what does shown + 1 produce?Show answerHide answer
Save this lesson to see this answer.
Question 9 of 10
null. A quantity must be present, nonnegative, and numeric; zero is allowed. What validation sequence meets all requirements?Show answerHide answer
Save this lesson to see this answer.
Question 10 of 10
What value and type are printed?
let amount = "6";
amount += 2;
amount++;
amount -= 4;
console.log(amount, typeof amount);
Show answerHide answer
Save this lesson to see this answer.
Set 3: Test comparisons and choose branches10 Practice Questions
Save this lesson to see every answer and practice every set.
Question 1 of 10
"16" === 16?Show answerHide answer
Save this lesson to see this answer.
Question 2 of 10
"24" < "8" evaluate to true?Show answerHide answer
Save this lesson to see this answer.
Question 3 of 10
0 ?? 5 evaluate to?Show answerHide answer
Save this lesson to see this answer.
Question 4 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 5 of 10
What is printed?
const points = 76;
let badge;
if (points >= 60) {
badge = "bronze";
} else if (points >= 75) {
badge = "silver";
} else {
badge = "none";
}
console.log(badge);
Show answerHide answer
Save this lesson to see this answer.
Question 6 of 10
const active = false;, what does active ? "Ready" : "Waiting" produce?Show answerHide answer
Save this lesson to see this answer.
Question 7 of 10
What value is printed?
const mode = "2";
let label = "idle";
switch (mode) {
case 2:
label = "fast";
break;
default:
label = "normal";
}
console.log(label);
Show answerHide answer
Save this lesson to see this answer.
Question 8 of 10
approved = false, isEditor = false, and isOwner = true, the code uses approved && isEditor || isOwner. What result does it give, and what condition enforces the full rule?Show answerHide answer
Save this lesson to see this answer.
Question 9 of 10
What text is printed?
let route = "";
switch (3) {
case 2:
route += "A";
break;
case 3:
route += "B";
case 4:
route += "C";
break;
default:
route += "D";
}
console.log(route);
Show answerHide answer
Save this lesson to see this answer.
Question 10 of 10
const distance = 42;, what are the values of 0 < distance < 20 and distance > 0 && distance < 20, respectively?Show answerHide answer
Save this lesson to see this answer.
Set 4: Trace errors and inspect execution10 Practice Questions
Save this lesson to see every answer and practice every set.
Question 1 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 2 of 10
total = total + 7; when total is 11. What value appears before Step over, and what value appears after it?Show answerHide answer
Save this lesson to see this answer.
Question 3 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 4 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 5 of 10
What happens when this script is loaded?
console.log("Begin");
let size = 4;
let size = 7;
Show answerHide answer
Save this lesson to see this answer.
Question 6 of 10
base: 13 number, extra: 4 string, and total: 134 string. Where should the fix start?Show answerHide answer
Save this lesson to see this answer.
Question 7 of 10
raw = "27", fee = 6, and total = "276" immediately before if (total > 100). What change fixes the false high-total classification?Show answerHide answer
Save this lesson to see this answer.
Question 8 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 9 of 10
What messages are printed before this code stops?
console.log("One");
let current = 5;
current += unknownStep;
console.log("Two");
Assume unknownStep has no declaration.
Show answerHide answer
Save this lesson to see this answer.
Question 10 of 10
Assume a fresh run for each input. What happens for null and for " 5 "?
const cleaned = input.trim() !== "" && input !== null;
const total = cleaned ? Number(input) + 2 : 0;
console.log(total);
Show answerHide answer
Save this lesson to see this answer.
Set 5: Repair calculations and decisions10 Practice Questions
Save this lesson to see every answer and practice every set.
Question 1 of 10
Math.floor(-3.2) return?Show answerHide answer
Save this lesson to see this answer.
Question 2 of 10
const count = 2;, what message does `Packed ${count} ${count === 1 ? "box" : "boxes"}` produce?Show answerHide answer
Save this lesson to see this answer.
Question 3 of 10
const label = "Draft.PDF";, what expression recognizes the PDF ending?Show answerHide answer
Save this lesson to see this answer.
Question 4 of 10
value. What test correctly detects that value as NaN?Show answerHide answer
Save this lesson to see this answer.
Question 5 of 10
What values do saved and total hold at the end?
let total = 8;
const saved = total++;
total *= 3;
total -= saved;
Show answerHide answer
Save this lesson to see this answer.
Question 6 of 10
count ?? 3 and count || 3 when count is 0, and which expression meets the rule?Show answerHide answer
Save this lesson to see this answer.
Question 7 of 10
A badge should be "gold" at 90 or more and "silver" at 70–89. What is wrong with this result, and what change repairs the overlapping thresholds?
const points = 94;
let badge;
if (points >= 70) {
badge = "silver";
} else if (points >= 90) {
badge = "gold";
} else {
badge = "none";
}
Show answerHide answer
Save this lesson to see this answer.
Question 8 of 10
if (!value) to reject invalid numeric input. The user enters "0", "bad", or "-2". Which failure pattern does this check have?Show answerHide answer
Save this lesson to see this answer.
Question 9 of 10
What is printed?
let stock = 0;
let status = "empty";
if (stock = 3) {
status = "ready";
}
console.log(stock, status);
Show answerHide answer
Save this lesson to see this answer.
Question 10 of 10
Show answerHide answer
Save this lesson to see this answer.
Set 6: Combine input, types, and control flow10 Practice Questions
Save this lesson to see every answer and practice every set.
Question 1 of 10
Show answerHide answer
Save this lesson to see this answer.
Question 2 of 10
typeof is "number", but it never equals itself. What value is it, and how should you test it directly?Show answerHide answer
Save this lesson to see this answer.
Question 3 of 10
What is printed?
const massKg = 2.75;
const message = `Load: ${(massKg * 4).toFixed(2)} kg`;
console.log(message);
Show answerHide answer
Save this lesson to see this answer.
Question 4 of 10
const cleaned = raw.trim(); and execution pauses there. How do you obtain and inspect the initialized cleaned value?Show answerHide answer
Save this lesson to see this answer.
Question 5 of 10
What is printed?
const raw = "18";
const fee = 3;
const total = raw * 2 + fee;
const label = raw + fee * 2;
console.log(total, label);
Show answerHide answer
Save this lesson to see this answer.
Question 6 of 10
For a string or null input, what value does this code assign to label when input is " "?
const input = " ";
const cleaned = input !== null && input.trim();
const label = cleaned ?? "Guest";
Show answerHide answer
Save this lesson to see this answer.
Question 7 of 10
What is printed?
const raw = "3";
let result = "";
switch (Number(raw)) {
case 3:
result += "M";
case 4:
result += "N";
break;
default:
result = "X";
}
console.log(result);
Show answerHide answer
Save this lesson to see this answer.
Question 8 of 10
The final log should print a shipping label for every branch. What repair preserves the intended outer result?
let label = "pending";
if (true) {
let label = "sent";
}
console.log(label);
Show answerHide answer
Save this lesson to see this answer.
Question 9 of 10
null, NaN, or a number. The valid interval includes 0 and 10. What test accepts exactly the numeric values in that interval?Show answerHide answer
Save this lesson to see this answer.
Question 10 of 10
8 + 12 + 36 / 3. What diagnosis and repair fit all the evidence?Show answerHide answer
Save this lesson to see this answer.
Stuck on your own question? Homework Help
Key Terms
A
Arithmetic operator
massKg * count uses multiplication to calculate the total mass from two numeric values.Assignment
count = count + 1; uses the previous count to calculate the value that replaces it.Async
async when no other script relies on it running first.B
Binding
const object preserves its binding because the name still refers to the same object.Block scope
const message declared inside an if body cannot be read after that body has finished executing.Boolean
heightM >= 2 returns a boolean that can decide whether a height meets a requirement.Boolean context
if test, but an empty string fails even though both values have type string.Branch
else branch can assign a delivery fee when the free-delivery condition has evaluated as falsy.Breakpoint
C
Camel case
firstName and totalMassKg show word boundaries while remaining valid JavaScript names.Coercion
"8" * 2, multiplication coerces the text to a number for the calculation and produces 16.Comment
// before a temporary log prevents it from running while keeping the text available for later.Comparison
massKg <= 20 includes exactly 20 and can be stored as the boolean result of a limit check.Compound assignment
let code = "7";, code += 2 stores "72" because compound addition still follows the text-joining rule.Concatenation
"Good" + " " + "morning" includes a space because the middle string explicitly supplies it.Conditional breakpoint
total > 200 skips ordinary smaller totals and pauses when a high result needs inspection.Conditional operator
"open" or "closed" from a boolean without writing two separate assignment branches.Console
6 * 7 in the page’s console shows 42 without adding a statement to the saved script.D
Data type
9 and "9" print similarly, but their types explain why adding one gives different results.De Morgan’s laws
Debugger
Declaration
let result; declares a variable before later code decides which value to store in it.Default case
"normal" in default when the input matches none of its named special modes.Defer
defer run in their HTML order even if the second download finishes first.Dynamic typing
let data = 5; data = "five";, typeof data reports the new string value’s type.E
Else-if chain
Escape sequence
creates a line break inside text even when the code is written on a single line.Explicit conversion
input before adding a fee makes it clear that the program expects a numeric total.Expression
price * count can supply a value to an assignment or to a template placeholder.External script
<script src="js/start.js"></script> connects the page to code in a child folder.F
Fall-through
Falsy value
0 skips if (quantity), even when zero is an allowed answer in the program.Floating point
0.1 + 0.2 can show extra final digits because the stored fractions are approximate.Formatting
(6).toFixed(2) inside a template displays "6.00" without changing the original numeric value.G
Global scope
let count established by an earlier classic script.I
Immutability
text = text.trim(); replaces the variable’s value with a new string instead of editing the old one.Index
"planet", index 0 holds "p" and index 5 holds "t"; index 6 is past the end.Infinity
8 / 0 returns Infinity, so division by zero does not always throw an exception.Initialization
const widthM = 4;, the number 4 is the initializer that makes the binding ready to be read.Inline script
<script>console.log("Hello");</script> block can print a message directly from an HTML page.Input validation
Interpolation
name = "Nora", interpolation in `Hello, ${name}` creates the greeting "Hello, Nora".J
JavaScript engine
console.log("Ready"); and the console shows "Ready".L
Logic error
Logical AND
&& so a measurement must satisfy both requirements.Logical NOT
!"0" is false because the nonempty string is truthy before its boolean value is reversed.Logical OR
Logpoint
Loose equality
"12" == 12 is true after conversion, so strict equality gives a more predictable type check.M
Method
label.toLowerCase() produces lowercase text, while omitting parentheses does not call the method.Method chaining
" Note ".trim().toLowerCase() first removes outer spaces and then changes the resulting case.Module script
<script type="module" src="js/main.js"></script> for its module code.N
NaN
"heavy" with Number() yields NaN, which Number.isNaN() can detect before arithmetic.Null
null, which the program can check before trying to call a string method.Nullish coalescing
count is 0, count ?? 3 keeps zero, while count || 3 replaces it with the fallback value.Numeric coercion
"14" - 2 produces 12 without changing a variable that originally stored the string.Numeric prefix parsing
parseFloat("6.2 kg") reads 6.2, while Number("6.2 kg") rejects the entire string as NaN.P
Placeholder
${...} part of a template literal where an expression is evaluated and its text form is inserted.`Mass: ${count * massKg} kg`, the placeholder calculates the total before inserting it.Postfix increment
let n = 3; const old = n++;, old receives 3 while the updated n becomes 4.Precedence
4 + 6 * 2, multiplication runs before addition, so the result is 16 instead of 20.Primitive value
R
Radix
parseInt("11", 10) reads decimal eleven, while parseInt("11", 16) reads decimal seventeen.ReferenceError
totl + 5 can trigger ReferenceError even though a correctly spelled variable total exists nearby.Relational comparison
"30" < "7" is true as text, but converting both values to numbers reverses that result.Remainder
478 % 100 gives the 78 cm left after the complete meters.Runtime error
S
Shadowing
let total = 2 inside a block leaves a separate outer total unchanged when the block ends.Short-circuit evaluation
input !== null first in an AND guard can prevent an unsafe call to input.trim() when input is null.Statement
let score = 8; console.log(score);, the declaration statement runs before the logging statement.Step over
Strict equality
"12" === 12 is false because matching digit text is still a different type from a number.Strict mode
"use strict"; helps expose a misspelled variable on its first assignment.String
"203" form text that can be joined or searched without becoming the number 203.Switch
"4" skips a numeric case 4: unless the input has been converted before the switch.Syntax error
T
Template literal
`Count: ${count}` places the current count alongside its descriptive label.Temporal dead zone
let price prevents an earlier read in that same block from reaching an outer price variable.Tolerance
Tracing
Truthy value
"false" and "0" pass truthiness tests because each contains characters rather than being empty.TypeError
text.length() treats a numeric property as a function, so the operation raises a TypeError.U
Unary plus
+"31" produces the number 31, whereas "31" + 1 joins text and produces "311".Undefined
let nickname;, reading the initialized binding gives undefined until another assignment occurs.V
Variable
distanceKm keeps the measured distance available for later calculations and messages.W
Watch expression
typeof total to Watch can expose the exact statement where a numeric value becomes a string.About this lesson
Make your own Study Materials
Turn your notes, slides and documents into Study Guides, Practice Questions, Flashcards and 6 more tools.