completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

The rest of the operators

Finish JavaScript's operator toolbox: ternary choices, type checks, property checks, delete, bitwise flags, shifts, comma, void, and the precedence table.

By the end, you can
  • 01
    Pick one of two valuesUse the ternary, ? :, for a small choice, and switch to if / else when choices pile up.
  • 02
    Check values and propertiesChoose the right check: typeof, instanceof, Array.isArray, in, or Object.hasOwn.
  • 03
    Read rare operatorsWork out what bitwise flags, shifts, the comma operator, void, and the precedence table do.

Operators you haven't met yet

An operator is a symbol or a word that works on values. For example, + adds two numbers. You already know many operators:

  • Math: +, -, *, and /.
  • Assignment: = and +=.
  • Comparisons: === and <.
  • Logical operators: &&, ||, and !.
  • Nullish coalescing, ??, and optional chaining, ?..

This lesson covers the rest. Some are common, like the ternary, ? :. Some are rare, like void. A few are powerful but easy to misuse, like the bitwise operators.

The goal is not clever code. In the Coding style lesson, you learned to avoid tricks that make readers stop and think. Here you learn what each operator means, so you can read it in real code. You also learn when an if statement or a well-named function would be clearer.

The short version
  • Use the ternary for one small choice between two values.
  • Pick the type check or property check that answers your exact question.
  • Bitwise operators turn a number into a 32-bit whole number first. Use them for on/off settings.
  • When you are not sure which operator goes first, add round brackets.
Real-life analogyOperators are tools in a toolbox

A toolbox holds more tools than you use every day. You don't cut wood with a measuring tape. When you know what each tool is for, you pick the right one. You also recognize a tool when someone else has used it.

In real life: A screwdriver you use every day
In JavaScript: +, ===, &&, and ??
In real life: A small pocket knife for quick jobs
In JavaScript: The ternary, for one small choice
In real life: A measuring tape that tells you what you have
In JavaScript: typeof, instanceof, in, and Object.hasOwn
In real life: A tiny special screwdriver for one rare job
In JavaScript: Bitwise operators, for on/off settings

The lesson goes in this order:

  1. The ternary, for a small choice.
  2. typeof and instanceof, for checking what kind of value you have.
  3. in and delete, for checking and removing properties.
  4. Bitwise operators, which work on the 0s and 1s inside a number.
  5. Shifts, the comma operator, and void.
  6. A table that shows which operator goes first.

The conditional (ternary) operator

STEP THROUGH

The values an operator works on are called its operands. In 2 + 3, the operands are 2 and 3. Most operators have one or two operands. The conditional operator is the only one with three. That is why people also call it the ternary operator. "Ternary" means "made of three parts". Its shape is:

The three parts of a ternaryJavaScript
condition ? valueIfTrue : valueIfFalse

Read it from left to right:

  1. JavaScript checks the condition.
  2. If the condition is truthy (it counts as true), the result is valueIfTrue, the part after ?.
  3. If not, the result is valueIfFalse, the part after :.

The whole ternary is an expression: a piece of code that produces a value. So you can store its result in a variable or return it from a function. You can also put it inside a template literal, a string written in backticks.

The ternary age >= 18 ? "adult" : "minor". The question age >= 18 is at the top. One arrow goes to the card "adult", used when the answer is true. The other arrow goes to the card "minor", used when the answer is false.age >= 18 ?"adult""minor"if trueif false
A ternary asks one question and gives back one of two values. If age >= 18 is true, you get "adult". If it is false, you get "minor".
Real-life analogyA ternary is like a wristband desk

At a concert, a staff member checks your age and hands you one of two wristbands. There is one question and two possible answers. You leave with exactly one wristband. A ternary is good at this kind of choice.

In real life: The question: "Are you 18 or older?"
In JavaScript: The condition: age >= 18
In real life: Yes: you get an adult wristband
In JavaScript: The value after ?: "adult"
In real life: No: you get a minor wristband
In JavaScript: The value after :: "minor"
In real life: The one wristband you leave with
In JavaScript: The value the ternary gives back
Pick one of two values with ? :
Step 0 of 5Ready
Your turn: follow the blue line

Guess which value the ternary picks. Then press Step to check, one step at a time.

Running in
  1. script
Next: line 1
const label = age >= 18 ? "adult" : "minor";const sentence = `This visitor is an ${label}.`;console.log(sentence);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Change line 1: which age should the ternary check?

Picking an age starts the run again. Guess what line 2 gives before you press Step.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

A good ternary is short enough to read in one go:

Pick a shipping labelPop out in the code editor (opens in a new tab)JavaScript
const shipping = cartTotal >= 500 ? "free" : "$5";
console.log(`Shipping is ${shipping}.`);

Before this code runs, cartTotal is set to 650. Line 1 checks whether cartTotal is 500 or more. It is, so shipping gets "free". Line 2 prints Shipping is free.

Here is one more small example. It picks a delivery price for a smaller cart:

Pick a delivery pricePop out in the code editor (opens in a new tab)JavaScript
const cartTotal = 420;
const delivery = cartTotal >= 500 ? "free" : "$5";
console.log(delivery);

Line 1 stores the cart total, 420. Line 2 checks whether 420 is 500 or more. It isn't, so delivery gets "$5". Line 3 prints $5.

A ternary can hold another ternary inside it. This is called a nested ternary. It makes the reader keep several questions in mind at once:

The same grade, as a nested ternary and as if/elsePop out in the code editor (opens in a new tab)JavaScript
const label = score >= 90 ? "A" : score >= 80 ? "B" : "keep practicing";

let readableLabel;
if (score >= 90) {
  readableLabel = "A";
} else if (score >= 80) {
  readableLabel = "B";
} else {
  readableLabel = "keep practicing";
}

Both versions give the same result. Line 1 is the nested ternary. Lines 3 to 10 do the same job with if and else. Each choice gets its own line, so it is easier to read.

The next lesson, if, else & conditions, covers if in full. For now, use this rule:

  • Use a ternary for one small choice between two values.
  • Use if / else when the choice needs more room.

typeof & instanceof

STEP THROUGH

typeof goes in front of a value. It gives back a string that names the kind of value. It works best for primitives: simple values that are not objects, like strings, numbers, and booleans. Its answers are "string", "number", "boolean", "bigint", "symbol", and "undefined". For a function, it says "function". For most objects, including arrays and dates, it just says "object".

instanceof asks a different question. A constructor is a function that makes objects, like Date or Array. value instanceof Date asks: "Was this object made by Date?" An array counts as an Array and also as an Object, because every array is a kind of object. The prototype chain lesson later explains exactly how JavaScript checks this.

Ask each value what kind it is
Step 0 of 6Ready
Your turn: follow the blue line

Step through the checks. Notice that typeof, instanceof, and Array.isArray each answer a different question.

Running in
  1. script
Next: line 1
console.log(typeof values[0]);console.log(Array.isArray(values[1]));console.log(values[1] instanceof Array);console.log(values[1] instanceof Object);console.log(values[3] instanceof String);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The table below helps you pick a check. Find your question in the first column. Use the check in the second column, and read the warning in the third.

Which type check to use for each question
Your questionCheck to useWatch out for
Is it a string, and not an object?typeof value === "string"new String("x") makes an object, so typeof says "object" for it.
Is it missing?value === null or value === undefinedtypeof null gives "object". This is an old mistake in JavaScript.
Is it an array?Array.isArray(value)typeof [] gives "object", so typeof can't tell.
Was it made by a certain constructor?value instanceof DateA value from another frame on the page, like an iframe, was made by that frame's own Date, so the check says false. You can learn this detail later.
Fun fact: typeof null is still object

This is a very old bug in JavaScript. Fixing it now would break existing websites, so it stays. The Data types lesson first showed it. Because of it, careful code checks for null directly, with value === null.

A common mistake is typeof value === "array". typeof never gives "array", so this check is always false. Use Array.isArray(value) for arrays. Use instanceof only when your question is "Which constructor made this object?"

in & delete

STEP THROUGH

"key" in object checks whether JavaScript can find a property with that name on the object. It gives true or false.

It also counts inherited properties. These are properties an object borrows. Every plain object can use some built-in methods, like toString, that it borrows from a shared built-in object. So "toString" in user is true, even though you never added toString to user.

To check only the properties stored on the object itself, use Object.hasOwn(object, "key"). Properties stored on the object itself are called own properties.

A cart called user holds name: "Ada". An arrow shows that user borrows from a box called built-in, which holds toString(). "toString" in user is true, because it looks in both. Object.hasOwn(user, "toString") is false, because it looks in user only.name: "Ada"userborrows fromtoString()built-in"toString" in usertrueObject.hasOwn(user, "toString")false
user holds only name. It borrows toString() from a built-in object. in looks in both places, so it says true. Object.hasOwn looks in user only, so it says false.

delete object.key removes a property from an object. This is useful for an object that you use as a list of named entries. It is not a good way to remove an item from an array. Deleting an array item leaves an empty place, called a hole. The array keeps the same length.

Check for properties, then remove them
Step 0 of 10Ready
Your turn: follow the blue line

Follow in, Object.hasOwn, and delete. Watch the array hole: the length stays 3, but index 1 is gone.

Running in
  1. script
Next: line 1
console.log("name" in user);console.log("toString" in user);console.log(Object.hasOwn(user, "toString"));delete user.age;console.log("age" in user);const letters = ["a", "b", "c"];delete letters[1];console.log(letters.length);console.log(1 in letters);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Before: three cards, "a", "b", and "c", at index 0, 1, and 2. After delete letters[1]: "a", an empty place, and "c". Nothing moved, so letters.length is still 3.before012"a""b""c"delete letters[1]after"a"empty"c"letters.length is still 3
delete letters[1] takes out the value at index 1 but leaves its place empty. That empty place is a hole. Nothing moves left, so length stays 3.
Strict mode and properties you can't delete

Some built-in properties are locked: JavaScript does not let you delete them. For example, the prototype property of Object is locked. In older non-strict scripts, delete Object.prototype fails quietly and gives false. In strict mode, it throws a TypeError. Modern modules use strict mode automatically, so a failed delete shows an error instead of doing nothing.

The table compares the three. Read each row as: this code, does it count borrowed properties, and when to use it.

in, Object.hasOwn, and delete side by side
CodeDoes it count borrowed properties?When to use it
"name" in userYes.When a borrowed property should count too, like checking whether a feature exists.
Object.hasOwn(user, "name")No.When you only care about data stored on this object itself.
delete user.ageIt doesn't check anything. It removes a property.When you want a property gone from an object.

For a plain data object, Object.hasOwn is usually clearer than in. It says the key belongs to this object itself.

To remove items from an array, use filter or splice. They close the gap, so the array gets shorter. delete leaves a hole instead.

Bitwise operators: & | ^ ~

INTERACTIVE

In the Numbers & math lesson, you learned that JavaScript stores numbers as 64-bit floating-point values. Bitwise operators work differently:

  1. First, JavaScript turns the number into a 32-bit whole number. Any fraction is dropped.
  2. It treats that whole number as a row of 32 bits. A bit is a tiny switch that is either 0 (off) or 1 (on).
  3. Then the operator works on the bits, one column at a time.
Real-life analogyBits are a row of light switches

Picture two rows of light switches. & asks which switches are on in both rows. | asks which are on in either row. ^ asks which switches are different. ~ flips every switch in one row.

In real life: Switch off
In JavaScript: Bit 0
In real life: Switch on
In JavaScript: Bit 1
In real life: Both switches must be on
In JavaScript: &
In real life: At least one switch is on
In JavaScript: |
In real life: Exactly one switch is on
In JavaScript: ^
In real life: Flip every switch
In JavaScript: ~
Bitwise AND on the last four bits. a = 12 is 1 1 0 0. b = 10 is 1 0 1 0. a & b is 1 0 0 0, which is 8, because only the first column has a 1 in both rows.a = 121100b = 101010a & b = 810001 only where both have 1
Each column is one switch, and shaded cards are switched on. & gives 1 only where both a and b have 1. Only the first column has two 1s, so the answer is 1000, which is 8.
Bitwise playground: the last eight bits
The code the playground runsPop out in the code editor (opens in a new tab)JavaScript
const a = 12; // 00001100const b = 10; // 00001010console.log(a & b);  // both bits are 1console.log(a | b);  // either bit is 1console.log(a ^ b);  // bits are differentconsole.log(~a);     // flip 32 bitsconsole.log(a << 1); // shift leftconsole.log(a >> 1); // shift rightconsole.log(a >>> 1); // unsigned shift right
Live bits12 and 10
a = 12
b = 10
a & b = 800001000both bits are 1
a | b = 1400001110either bit is 1
a ^ b = 600000110bits differ
~a = -1311110011flip all 32 bits
a << 1 = 2400011000slide left
a >> 1 = 600000110slide right, keep the sign
a >>> 1 = 600000110slide right, fill with 0
Try it yourself
Change a value:

a is 12 (00001100 in bits), and b is 10 (00001010 in bits). JavaScript turns both into 32-bit whole numbers first. This playground shows only the last 8 bits, so they fit on the screen. Click a bit to switch it on or off.

You see only the last 8 bits. ~ and >>> still work on all 32 bits. That is why ~12 is negative.

The next code shows three results that surprise people. Each one comes from the 32-bit rule:

Three surprising results of the 32-bit rulePop out in the code editor (opens in a new tab)JavaScript
console.log(2 ** 32 | 0); // 0: wraps to a 32-bit signed integer
console.log(~5);        // -6: flip all 32 bits
console.log(-1 >>> 0);  // 4294967295: read all bits as unsigned
  1. ** means "to the power of"; you'll see it again below. 2 ** 32 is 4294967296. That number needs 33 bits, so its 32-bit version is 0.
  2. ~5 flips all 32 bits of 5. The result is -6. For whole numbers, ~x always equals -(x + 1).
  3. -1 has all 32 bits switched on. >>> 0 reads those bits as a number that can't be negative, called an unsigned number. That gives 4294967295.

A clear, real use of bitwise operators is flags. A flag is one bit that stands for one yes/no setting, like a permission. Give each permission its own bit. Then:

  • | combines flags.
  • & tests whether one flag is on.
  • ^ switches one flag on or off.
Permission flagsPop out in the code editor (opens in a new tab)JavaScript
const READ = 1;    // 001
const WRITE = 2;   // 010
const EXECUTE = 4; // 100
let permissions = READ | WRITE;
console.log((permissions & WRITE) !== 0);
permissions = permissions ^ WRITE;
console.log((permissions & WRITE) !== 0);

Lines 1 to 3 give each permission its own bit. Line 4 combines READ and WRITE. Line 5 tests the WRITE bit and prints true. Line 6 switches WRITE off with ^. Line 7 tests again and prints false.

Remember the 32-bit rule when you see value | 0. It drops the fraction, but it gives wrong answers for very large numbers. To drop the fraction from a price or any other normal number, use Math.trunc(value).

Shifts, comma & void

STEP THROUGH

Shift operators slide all 32 bits to the left or to the right:

  • << slides bits left. It fills the empty places on the right with 0.
  • >> slides bits right. It keeps the leftmost bit, called the sign bit, which says whether the number is negative. So negative numbers stay negative.
  • >>> slides bits right and fills the left with 0. The result is never negative: it is unsigned.

Before the shift examples, here is one more math operator. ** is the exponent operator. It raises a number to a power: 2 ** 3 means 2 × 2 × 2, which is 8. It is not a bitwise operator, and its result is a normal number.

A power and a default namePop out in the code editor (opens in a new tab)JavaScript
const boxes = 2 ** 3;
let displayName = "";
displayName ||= "Guest";
console.log(boxes, displayName);

Line 1 stores 8 in boxes. Line 2 sets displayName to an empty string. Line 3 uses ||=, the logical OR assignment. It writes "Guest" only when the variable is falsy (it counts as false). An empty string is falsy, so displayName becomes "Guest". Line 4 prints 8 Guest.

This is handy for a missing name. But ||= also replaces values you may want to keep, like 0 or false, because they are falsy too. Use ??= when only null and undefined should count as missing.

Back to shifts. They are useful for flags and for binary formats, which is data stored as raw bits. They are not for everyday math, because they lose anything that doesn't fit in 32 bits. When the number itself matters, use multiplication, division, or BigInt.

Three shifts and their resultsPop out in the code editor (opens in a new tab)JavaScript
console.log(5 << 1);  // 10
console.log(5 >> 1);  // 2
console.log(-1 >>> 0); // 4294967295

In bits, 5 is 101. Line 1 slides it left to 1010 in bits, which is 10. Line 2 slides it right to 10 in bits, which is 2; the rightmost bit falls off. Line 3 reads -1 as an unsigned number, like before.

The last two operators mostly appear in old or unusual code:

  • The comma operator runs expressions from left to right and keeps only the last value.
  • The void operator runs an expression, throws away its value, and gives undefined.
The comma keeps the last value; void keeps none
Step 0 of 7Ready
Your turn: follow the blue line

The comma runs each part in order and keeps the last value. void always gives undefined.

Running in
  1. script
Next: line 1
i++, j--;const kept = (1, 2, 3);const swallowed = void kept;console.log(i, j, kept, swallowed);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Old code you may see, but shouldn't copy

Old code sometimes used void 0 to get undefined. It also used <a href="javascript:void(0)"> to make a link do nothing when clicked. Today, use a real <button> with a click handler, and write undefined directly.

The operator precedence table

SORTING GAME

When one line has several operators, JavaScript must decide which operator gets its values first. This order is called precedence. You know it from maths: in 2 + 3 * 4, the * goes first, so the answer is 14.

Precedence decides how the code is grouped. It does not always decide which part runs first: JavaScript still works out most operands from left to right. The simple rule for you: when you mix operators you don't know well, add round brackets around the part that should go first.

Read the table from top to bottom. Level 1 goes first, and level 19 goes last. The last column is a short note to help you remember.

Operator precedence, from first to last
LevelGroupOperatorsNote
1Grouping(...)Round brackets make the part inside go first.
2Properties and calls., [], ?., ()Reading a property or calling a function happens before the operators around it.
3Update after usex++, x--Gives the current value, then changes the variable.
4One-value operators!, ~, +x, -x, typeof, void, deleteOperators that take one value go before operators that take two.
5Power**Groups from the right: 2 ** 3 ** 2 means 2 ** (3 ** 2).
6Multiply and divide*, /, %Goes before adding and subtracting, like in maths.
7Add and subtract+, -+ also joins strings.
8Shifts<<, >>, >>>Slide the 32 bits left or right.
9Compare and check<, >, <=, >=, in, instanceofCompare sizes, or check for a property or a constructor.
10Equality==, !=, ===, !==Prefer === and !==.
11Bitwise AND&1 where both bits are 1.
12Bitwise XOR^1 where the two bits are different.
13Bitwise OR|1 where either bit is 1.
14Logical AND&&Gives the left side if it is falsy; otherwise the right side.
15Logical OR||Gives the left side if it is truthy; otherwise the right side.
16Nullish coalescing??Uses the right side only when the left side is null or undefined.
17Conditionalcondition ? a : bPicks one of two values.
18Assignment=, +=, ??=, &&=, ||=Stores a value in a variable.
19Comma,Runs left to right and keeps the last value.

Logical assignment works the same way as its longer form:

  • name ||= "Guest" writes only when name is falsy.
  • name ??= "Guest" writes only when name is null or undefined.

When an assignment is mixed with other operators, round brackets make it clearest.

Now sort some cards. For each one, decide: does it go before +, at the same level as +, or after +? If you are unsure, the feedback tells you where the operator sits.

Does it go before or after +?
  • getTotal()
  • typeof value
  • price * tax
  • subtotal + tax
  • total - discount
  • flags << 1
  • ready && saved
  • ok ? a : b
  • first(), second()
Try it yourself
0 of 9 correct

Place each card. You don't need to learn the whole table. The goal is to notice when round brackets would make code clearer.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Where you'll use this

In everyday front-end code, these operators show up in a few places:

  • A ternary picks a CSS class, a label, or a short message: const tone = error ? "danger" : "success";
  • typeof checks data that comes from outside your code, like a server's answer, when it might be a string, a number, or a function.
  • Array.isArray checks data you didn't create before you call array methods on it.
  • Object.hasOwn reads plain object data when borrowed properties should not count.
  • Bitwise flags appear in libraries, file permissions, graphics, and some browser features. You will read them more often than you write them.
Describe an uploaded file with two checksPop out in the code editor (opens in a new tab)JavaScript
function describeUpload(file) {
  const kind = Array.isArray(file.tags) ? "tagged" : "untagged";
  const owner = Object.hasOwn(file, "owner") ? file.owner : "unknown";
  return `A ${kind} file owned by ${owner}.`;
}

Line 2 uses a ternary with Array.isArray to pick "tagged" or "untagged". Line 3 uses a ternary with Object.hasOwn: it reads file.owner only when owner is stored on file itself. Line 4 builds the sentence.

Common misconceptions

"A ternary is always shorter, so it is always better."

Shorter is not the same as clearer. A ternary is good for one small label choice. When there are more than two choices, use if / else or an object that maps each case to its value.

"typeof tells me the exact type of everything."

typeof null is "object". Arrays and dates are "object" too. Use a more exact check, like Array.isArray, when you need one.

"in means the property is stored on the object."

in also counts borrowed properties, like toString. Use Object.hasOwn to check only the properties stored on the object itself.

"delete removes an array item, like splice."

delete leaves a hole, and the length stays the same. Use splice or filter when you want a shorter array.

"Bitwise operators are just faster math."

They turn numbers into 32-bit whole numbers first, which can change the result. Tricks like ~~x hide that change and make code harder to read, which goes against the Coding style lesson.

"If I know the precedence table, I don't need brackets."

Experienced developers still add round brackets when mixed operators could slow a reader down. Clear code is more important than a short line.

Practice: the rest of the operators

5 EXERCISES
Exercise 1 · Warm-upPredict a ternary

Work out which value the ternary picks before you run the code.

Starter codePop out in the code editor (opens in a new tab)JavaScript
const age = 15;
const label = age >= 18 ? "adult" : "minor";
console.log(label);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeRewrite a nested ternary

    Rewrite the nested ternary as an if / else if / else chain.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const label = score >= 90 ? "A" : score >= 80 ? "B" : "keep practicing";

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeBuild permission flags

      Predict the two values the code prints.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const READ = 1;
      const WRITE = 2;
      const EXECUTE = 4;
      let permissions = READ | EXECUTE;
      console.log((permissions & WRITE) !== 0);
      permissions = permissions | WRITE;
      console.log((permissions & WRITE) !== 0);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeCheck for an own property

        Which call checks only the properties stored on user itself?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const user = { name: "Ada" };
        console.log(Object.hasOwn(user, "toString"));

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengePredict two 32-bit results

          Predict both lines. Here the hidden change to a 32-bit number matters.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          console.log(~5);
          console.log(-1 >>> 0);

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            8 QUESTIONS

            Take your time. Every answer explains why it is right or wrong. The code questions use what JavaScript really prints.

            Lesson quiz · 8 questionsScore: first tries count
            1. Question 1 of 8What does the ternary print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const age = 20;
              console.log(age >= 18 ? "adult" : "minor");

              Choose an answer to see the explanation.

            2. Question 2 of 8Which check is the reliable way to detect arrays?

              Choose an answer to see the explanation.

            3. Question 3 of 8What do in and Object.hasOwn print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const user = { name: "Ada" };
              console.log(("toString" in user) + " " + Object.hasOwn(user, "toString"));

              Choose an answer to see the explanation.

            4. Question 4 of 8What does deleting an array element print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const letters = ["a", "b", "c"];
              delete letters[1];
              console.log(letters.length + " " + (1 in letters));

              Choose an answer to see the explanation.

            5. Question 5 of 8What do these bitwise expressions print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(~5 + " " + (-1 >>> 0));

              Choose an answer to see the explanation.

            6. Question 6 of 8Which expression tests whether the WRITE flag is on?

              Choose an answer to see the explanation.

            7. Question 7 of 8What do the comma and void print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const value = (1, 2, 3);
              console.log(value + " " + (void value));

              Choose an answer to see the explanation.

            8. Question 8 of 8Which operator in this lesson goes last, at the bottom of the precedence table?

              Choose an answer to see the explanation.

            Key takeaways

            • A ternary picks one of two values: condition ? valueIfTrue : valueIfFalse.
            • typeof is best for primitives. Use Array.isArray for arrays, and instanceof to ask which constructor made an object.
            • in also counts borrowed properties. Object.hasOwn checks only the object itself.
            • delete removes object properties. On arrays it leaves holes, and length stays the same.
            • Bitwise operators turn numbers into 32-bit whole numbers. Flags are a good use; clever number tricks are not.
            • The comma operator and void are rare. Learn to recognize them, but don't reach for them first.
            • Precedence decides which operator goes first, but round brackets show your meaning to other people.

            Remember the one-liner.
            The "other operators" are special tools. Use one when it makes a choice, a check, a flag, or a grouping clearer than the longer way of writing it.

            Up next: if, else & conditions, where a choice can hold whole blocks of code.

            CompleteFrontend Clear concepts. Working examples.