Warm-up · Activity 1 of 7
// B2.4 · ~30 min · Beginner
Equality and sameness
After this lesson you compare values with === and !==, predict what == does when the types differ, test for NaN correctly, and know when two arrays or two strings count as equal or smaller.
You will be able to
- Compare values with === and !==, and predict what == converts when the types differ
- Handle NaN and -0: Number.isNaN, and Object.is for sameness
- Compare arrays and objects by reference, and strings with < and > against numbers
Predict · Activity 2 of 7
Predict before you read on: what does this print?
console.log(1 == "1", 1 === "1");Practice · Activity 3 of 7
NaN === NaN is false. Fill in the method name so that the line compares by sameness and prints true.
console.log(Object.____(NaN, NaN));console.log(Object.(NaN, NaN));Practice · Activity 4 of 7
What does this print?
const a = [1, 2]; const b = [1, 2]; const c = a; console.log(a === b, a === c);Practice · Activity 5 of 7
Match each comparison to its result and the reason.
Brain teaser · Activity 6 of 7
Brain teaser. What does this print?
console.log("10" < "9", 10 < 9, "10" < 9);Apply · Activity 7 of 7
Mini-task. A form gives you the text "42", and the program has stored the number 42. Print the loose comparison, the strict one, and the strict one after Number() has converted the text. Then convert the text "forty-two" and print whether the result is NaN, with Number.isNaN. Predict each line before you run it.
Check your work against this list
Build it yourself
Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.
Worked example
An equality lab
This program compares the same kinds of values in different ways and prints each question with its answer, using template literals. It covers a string against a number, a NaN from a failed conversion, two arrays, and strings against numbers with <. Run it, then change a value, such as typed to "7.0" or copy to cart, and predict each line before you run it again.
main.js
// The same values, compared in different ways.
const typed = "7";
const stored = 7;
console.log(`typed == stored: ${typed == stored}`);
console.log(`typed === stored: ${typed === stored}`);
console.log(`Number(typed) === stored: ${Number(typed) === stored}`);
const result = Number("seven");
console.log(`result === NaN: ${result === NaN}`);
console.log(`Number.isNaN(result): ${Number.isNaN(result)}`);
console.log(`Object.is(result, NaN): ${Object.is(result, NaN)}`);
const cart = ["tea", "milk"];
const sameCart = cart;
const copy = ["tea", "milk"];
console.log(`cart === sameCart: ${cart === sameCart}`);
console.log(`cart === copy: ${cart === copy}`);
console.log(`cart[0] === copy[0]: ${cart[0] === copy[0]}`);
console.log(`"10" < "9": ${"10" < "9"}`);
console.log(`10 < 9: ${10 < 9}`);
Run it with
node main.jsOutput
typed == stored: true
typed === stored: false
Number(typed) === stored: true
result === NaN: false
Number.isNaN(result): true
Object.is(result, NaN): true
cart === sameCart: true
cart === copy: false
cart[0] === copy[0]: true
"10" < "9": true
10 < 9: false- == says the text "7" equals the number 7; === says no, and Number() makes the strict comparison true.
- result === NaN is false even though result is NaN: test NaN with Number.isNaN or Object.is.
- sameCart is the same array as cart; copy only looks the same. Comparing items compares the strings inside.
- As text, "10" comes before "9"; as numbers, it does not.
Change it and run it
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Exercises
Exercise 1 of 2
No hidden conversions
The program compares a typed PIN with a stored one, and two other values, using == and !=. Its first three checks print true, but each compares values of different types, so they should print false, and the last one should print true. Change the operators to === and !== so that nothing is converted. Do not change the values.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
Run it first: == converts "0042" to the number 42, and "" to 0, before comparing.
Hint 2
Replace each == with ===. The strict version checks the type too.
Hint 3
The last check asks whether the two differ: != becomes !==.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const typedPin = "0042";
const storedPin = 42;
const input = "";
const answer = "1";
console.log("PIN matches:", typedPin === storedPin);
console.log("input is zero:", input === 0);
console.log("answer is true:", answer === true);
console.log("PIN differs:", typedPin !== storedPin);
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const typedPin = "0042";
const storedPin = 42;
const input = "";
const answer = "1";
console.log("PIN matches:", typedPin == storedPin);
console.log("input is zero:", input == 0);
console.log("answer is true:", answer == true);
console.log("PIN differs:", typedPin != storedPin);
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('prints four lines', async () => {
const got = await lines();
assert.equal(got.length, 4, `the program printed ${got.length} line(s), expected 4`);
});
test('the PIN does not match without conversion', async () => {
const got = await lines();
assert.equal(got[0], 'PIN matches: false', `the first line is ${JSON.stringify(got[0])}, expected "PIN matches: false"`);
});
test('the empty input is not zero', async () => {
const got = await lines();
assert.equal(got[1], 'input is zero: false', `the second line is ${JSON.stringify(got[1])}, expected "input is zero: false"`);
});
test('the text "1" is not the value true', async () => {
const got = await lines();
assert.equal(got[2], 'answer is true: false', `the third line is ${JSON.stringify(got[2])}, expected "answer is true: false"`);
});
test('the PIN differs strictly', async () => {
const got = await lines();
assert.equal(got[3], 'PIN differs: true', `the fourth line is ${JSON.stringify(got[3])}, expected "PIN differs: true"`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsExercise 2 of 2
Three wrong answers
Each line of this program prints the wrong answer, and there is no error to help. It should print price is NaN: true, then same basket: true, then 10 is less than 9: false. Fix the NaN test, make saved the very same array as basket instead of a copy, and compare the two texts as numbers with Number(). Keep the labels as they are.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the JavaScript runner (up to 0.1 MB) and keeps it cached. Your code runs in your browser’s own engine and stays on your device.
Hints
Hint 1
NaN is not equal to anything, itself included, so price === NaN is always false. Number.isNaN(price) asks the right question.
Hint 2
Two array brackets make two arrays. const saved = basket; makes saved point to the same one.
Hint 3
Two strings are compared character by character. Number(small) < Number(large) compares 10 and 9.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
const price = Number("12,50");
console.log("price is NaN:", Number.isNaN(price));
const basket = ["apple", "pear"];
const saved = basket;
console.log("same basket:", basket === saved);
const small = "10";
const large = "9";
console.log("10 is less than 9:", Number(small) < Number(large));
Run it on your computer
Install ECMAScript 2026 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.js
const price = Number("12,50");
console.log("price is NaN:", price === NaN);
const basket = ["apple", "pear"];
const saved = ["apple", "pear"];
console.log("same basket:", basket === saved);
const small = "10";
const large = "9";
console.log("10 is less than 9:", small < large);
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
const lines = async () => (await runMain()).trimEnd().split('\n');
test('finds the NaN', async () => {
const got = await lines();
assert.equal(got[0], 'price is NaN: true', `the first line is ${JSON.stringify(got[0])}, expected "price is NaN: true"`);
});
test('saved is the same array as basket', async () => {
const got = await lines();
assert.equal(got[1], 'same basket: true', `the second line is ${JSON.stringify(got[1])}, expected "same basket: true"`);
});
test('compares 10 and 9 as numbers', async () => {
const got = await lines();
assert.equal(got[2], '10 is less than 9: false', `the third line is ${JSON.stringify(got[2])}, expected "10 is less than 9: false"`);
});
test('prints exactly three lines', async () => {
const got = await lines();
assert.equal(got.length, 3, `the program printed ${got.length} line(s), expected 3`);
});
package.json
{
"type": "module"
}
package.json tells Node.js that the .js files are modules; keep it in the folder.
Run the program:
node main.jsRun the checks (needs learnrun.js in the same folder):
node --testDownload learnrun.jsCommon mistakes
A single = where === belongs
const total = 10;
console.log(total = 10);
What Node.js prints
TypeError: Assignment to constant variable.Why, and the fix
One = assigns a value; it does not compare. Here it tries to give the const total a new value, and the program stops. With a let variable it would be worse: the value would change without any error, and the line would print 10. To compare, write total === 10.
A small n in Number.isNaN
const result = Number("abc");
console.log(Number.isNan(result));
What Node.js prints
TypeError: Number.isNan is not a functionWhy, and the fix
Number exists, but it has no method isNan: the name is isNaN, with a capital N at both ends, like the value NaN. Names are case-sensitive, and calling a name that is not a function is a TypeError. Write Number.isNaN(result).
Four equals signs
const x = 5;
console.log(x ==== 5);
What Node.js prints
SyntaxError: Unexpected token '='Why, and the fix
JavaScript has ==, === and their opposites != and !==, but no ==== and no !===. After ===, the next = cannot start anything, so the file cannot be read, and no line runs. Use exactly three signs for strict equality: x === 5.
JavaScript in the browser: your browser’s own engine, in a sandboxed worker. Syntax errors are located with acorn 8.18.0, MIT. Licence and source
Exit ticket
5 questions, no hints. Score 80% or more to complete the lesson.
Finish every activity above to unlock the exit ticket.