Skip to main content

Command Palette

Search for a command to run...

JS Operators: The Hidden Mechanics of Every Web App

Level Up Your Logic with RPG Mechanics

Published
13 min read
JS Operators: The Hidden Mechanics of Every Web App

Operators are a fundamental part of any programming language, and their necessity comes down to one simple idea: a program that can't manipulate data is useless. Data alone is meaningless. Storing a value like 100 in a variable does nothing on its own. You need a way to act on it, increase it, compare it, combine it, transform it, make decisions on it. Operators are the mechanism that makes data dynamic. Variables hold data, functions organize code, but operators are what actually compute things. They are the primitive actions from which all logic is built, every algorithm, every formula, every condition ultimately reduces to a sequence of operator evaluations.

Every video game runs on rules and mechanics. When you swing a sword, the game calculates damage. When you pick up a health potion, it adds HP. JavaScript operators are exactly that: the game mechanics built into the language that make things happen between values.

In any RPG, two values enter a battle screen, a player and an enemy. An operator is the action between them. Slash (subtract), heal (add), block (compare). The result determines the outcome.

The two values an operator works on are called operands, such that operand OP operand = result.

Types Of Operators

JavaScript has four families of operators:

Arithmetic Operators

Arithmetic operators are used for performing mathematical calculations in JavaScript.

Your warrior swings for 10 damage. The enemy has 40 HP. The engine calculates: 40 - 10 = 30 HP . Your party of 3 shares 10 potions: 10 / 3 = 3.33. The remainder? 10 % 3 = 1 potion left over.

Operator Name Game Analogy Example Result
+ Addition Collecting gold 50 + 30 80
- Subtraction Taking damage 100 - 35 65
* Multiplication Critical hit multiplier 20 * 2.5 50
/ Division Splitting loot 100 / 4 25
% Modulo Leftover loot after splitting 17 % 5 2
** Exponentiation Spell power scaling 2 ** 8 (2^8) 256
const playerHP = 100;
const enemyDamage = 35;
const critMultiplier = 2.5;
const partySize = 4;
const loot = 100;
const upgradeShards = 21;
const perUpgradeShards = 6;

console.log(playerHP - enemyDamage);          // HP after hit
console.log(enemyDamage * critMultiplier);    // Critical damage
console.log(loot / partySize);                // Gold per player
console.log(upgradeShards % perUpgradeShards);// Leftover upgrade shards
//console
65      // 100 - 35 = 65 HP remaining
87.5    // 35 * 2.5  critical damage
25      // 100 / 4 = 25 loot each
3       // 21 % 6 -> 3 left over

The String Glitch

The + operator has a hidden second mode. If one of the values is a string, instead of adding numbers it concatenates them together like text. This is JavaScript's most notorious "glitch" which produces completely wrong output.

// Player typed their level in a form & comes in as a STRING
const playerLevel = "5";   // This is TEXT, not a number
const bonusLevels  = 3;

// '+' thinks it's joining strings
console.log(playerLevel + bonusLevels);    // 53

// fix: Convert to number first
console.log(Number(playerLevel) + bonusLevels);    // 8

// Why other operators don't have this glitch:
console.log(playerLevel - bonusLevels);  // 2: '-' forces numeric
console.log(playerLevel * bonusLevels);  // 15: '*' forces numeric
💡
Data from forms, APIs, and user input always arrives as a string. Before doing any arithmetic, wrap it in Number(value) or parseInt(value, 10). Always validate before performing an operation on them.

Comparison Operator

A comparison operator compares its operands and returns a logical value based on whether the comparison is true. The operands can be numerical, string, logical, or object values. If the two operands are not of the same type, JavaScript attempts to convert them to an appropriate type for the comparison, with an exception of === and !== operators.

const playerID1 = 100;
const playerID2 = 200;
Operator Meaning Game Example Result
== Loose equal (type ignored) playerID1 == "100" true
=== Strict equal (type matters) playerID1 === 100 true
!= Loose not-equal playerID1 != "200" true
!== Strict not-equal playerID1 !== playerID2 true
> Greater than playerID1 > 0 true
< Less than playerID1 < 200 true
>= Greater or equal playerID2 >= 100 true
<= Less or equal 100 <= 20 true
const playerXP    = 720;
const playerLevel = 8;
const bossLevel   = 10;
const playerHP    = 15;

console.log(playerXP >= 500);       // Enough XP to unlock zone?
console.log(playerLevel < bossLevel); // Underleveled for boss?
console.log(playerHP <= 20);         // Danger zone health?
console.log(playerLevel === 8);       // Exact level check
// output
true // 720 >= 500 | Zone unlocked
true // 8 < 10 | Underleveled
true // 15 <= 20 | Low health warning
true // Exact match

== vs ===

== Loose Equality === Strict Equality
Only checks the value Checks value AND type
Secretly converts types first No secret conversions
Lets impostors through Rejects all impostors
Unpredictable behavior Predictable, safe
AVOID in real code ALWAYS use this
// Imagine checking if player ID matches
const realID   = 42;          // Number
const inputID  = "42";        // String from a form

// == is the bribed guard. lets the impostor through
console.log(realID ==  inputID);  // "42" gets converted to 42
console.log(0      ==  false);    // Both "falsy", treated equal
console.log(""     ==  false);    // Empty string == false??
console.log(null   ==  undefined); // This one's an exception

// === is the true guard. rejects mismatches
console.log(realID === inputID);  // number !== string
console.log(0      === false);   // number !== boolean
console.log(""     === false);   // string !== boolean
//output of ==
true // Impostor passed, "42" secretly became 42
true // 0 and false slipped through
true // Empty string == false? 
true // Special JS rule for null/undefined

// output of ===

false // Impostor rejected, different types
false // Different types, not equal
false // Different types, not equal
💡
Use === every single time. No exceptions.

Logical Operators

Logical operators are typically used with Boolean (logical) values; when they are, they return a Boolean value.

The dungeon gate glows, it has two locks giving two conditions. Your party needs a magic key AND the blessing of fire. Both must be true. One lock alone won't open it. That's &&. The tavern, however, accepts gold OR an adventurer's badge, either one works. That's ||.

Operator Name Game Meaning Example Result
&& AND All locks must open hasKey && hasHP true
OR Any one key works
! NOT Flip the state !isBanned true
?? Nullish coalescing Use the backup if the first item is missing (null or undefined) savedSkin??'Default'

Truth Table

  • AND

    A B A && B
    false false false
    false true false
    true false false
    true true true
  • OR

| A | B | A || B | | --- | --- | --- | | false | false | false | | false | true | true | | true | false | true | | true | true | true |

  • NOT

    A !A
    false true
    true false

JavaScript's logical engine is lazy by design. With &&: the moment the first condition is false, it stops. No point checking the rest. With ||: the moment the first is true, it stops.

// || as a default value fallback
const savedName  = "";
const playerName = savedName || "Anonymous Hero";
// "" is falsy, falls back
console.log(playerName);     // Anonymous Hero

// && safely accessing nested data without crashing
const player = null;           // Player not loaded yet
const hp     = player && player.hp;  // && stopped at null
console.log(hp);               // null 

Nullish Coalescing (?? ): OR (|| ) treats 0 and "" as falsy which is a bug risk, ?? only falls back for null or undefined. Use ?? when setting defaults in modern code: score ?? 0 won't override a valid score of 0.

const isLoggedIn     = true;
const isMember       = true;
const isBanned       = false;
const hasWeapon      = false;
const hasMagicStaff  = true;
const playerGold = 0;          
const playerTitle = null;      


// AND: all conditions must pass
const canEnterGuild = isLoggedIn && isMember && !isBanned;
console.log("Enter guild:", canEnterGuild);  // Enter guild: true 
// Every condition is true

// OR: any one works
const isArmed = hasWeapon || hasMagicStaff;
console.log("Is armed:", isArmed);    // Is armed: true 
// no sword but has staff (atleast one true)

// NOT: flip the boolean
console.log("Is NOT banned:", !isBanned); // Is NOT banned: true

// Combined gate check
const canRaid = canEnterGuild && isArmed;
console.log("Ready to raid?", canRaid); // Ready to raid? true

// Nullish Coalescing: Provide a fallback only if data is null/undefined
const displayGold = playerGold ?? 100;    
const displayTitle = playerTitle ?? "Noob"; 

console.log("Current Gold:", displayGold); // Current Gold: 0 
//The fallback 100 is ignored because 0 is a valid number

console.log("Player Rank:", displayTitle); // Player Rank: Noob
// The fallback triggers because the title is null

Assignment Operator

Every game has a save file, a place where your stats are stored and updated as you play. Assignment operators are JavaScript's save system. They don't just calculate, they write the result back into the variable, updating the game state. An assignment operator assigns a value to its left operand based on the value of its right operand.

When you collect gold in a dungeon, the game doesn't just note it — it saves your new total: gold += 50. When you take damage, your HP is updated: hp -= 35. Every operator here modifies the variable in-place and commits it to memory.

Operator Meaning Equivalent Game Use
= Assign Set starting stats
+= Add & save x = x + n Collect gold / heal HP
-= Subtract & save x = x - n Take damage / spend mana
*= Multiply & save x = x * n Apply multiplier / buff
/= Divide & save x = x / n Split resources
%= Modulo & save x = x % n Calculate leftover ammo
??= Nullish coalescing & save x ?? (x = n) Null/Undefined check before assignment
// 🎮 A dungeon run tracking player state in real time
let hp    = 100;               // Start with full HP
let gold  = 0;                 // Empty pockets
let mana  = 80;                // Mana pool
let companion = undefined;     // A pet not found yet

// Enemy hits you
hp -= 35;
console.log("HP after hit:", hp);    //HP after hit: 65

// Drink a healing potion
hp += 20;
console.log("HP after potion:", hp);   // HP after potion: 85

// Collect treasure chest
gold += 150;
console.log("Gold:", gold);    // Gold: 150

// Cast a fireball (costs 30 mana)
mana -= 30;
console.log("Mana remaining:", mana);    //Mana remaining: 50 

// Double gold with ring of fortune (buff!)
gold *= 2;
console.log("Gold after buff:", gold); // Gold after buff: 300

// Assign a companion pet
companion ??= "Spirit Wolf";
console.log("Companion Slot:", companion); // Companion Slot:Spirit Wolf"
💡
Assignment operators only work with let and not const. Start every variable as const. Only define with let when you know the value will change (like HP, gold, mana). This prevents you from accidentally mutating variables that should never change.

The Quest of Operators

A real game engine combines all four operator types every frame. Here's a mini dungeon run that uses every operator family learned so far in a single cohesive script.

// DUNGEON RUN

// ASSIGNMENT: Set starting stats
let hp          = 80;
let gold        = 0;
const playerLvl = 5;
const bossLvl   = 8;
const hasSword  = true;
const isBanned  = false;

// NULLISH: Player may not have a name saved yet
const savedName  = null;
const playerName = savedName ?? "Anonymous Hero";   // if null, use fallback

// null ?? "Anonymous Hero" = fallback used
console.log("Playing as:", playerName);    // Playing as: Anonymous Hero

// NULLISH: Bonus multiplier might not be configured
const configBonus = undefined;
const bonusMult   = configBonus ?? 1;     // undefined: default to 1

// undefined ?? 1 = fallback used
console.log("Bonus multiplier:", bonusMult);    // Bonus multiplier: 1

// ARITHMETIC: Calculate damage taken
const bossDmg = 25 * 1.5;    // Boss crit: 25 * 1.5
hp -= bossDmg;                // update HP

// NULLISH: HP display = 0 is a valid value, don't replace it
const displayHP = hp ?? "Unknown";   // only replaces null/undefined

// 42.5 is a real value — ?? leaves it alone
console.log("HP on screen:", displayHP);    // HP on screen: 42.5

// COMPARISON: Check danger status
const inDanger = hp < 30;

// LOGICAL: Can player enter the boss arena?
const canFight = hasSword
               && !isBanned
               && hp > 0;

// ARITHMETIC + ASSIGNMENT: Collect rewards
if (canFight) {
  gold += 200;
  gold *= playerLvl >= 5 ? 1.5 : 1;
}

console.log("HP after boss:",  hp);    // HP after boss: 42.5
console.log("In danger?",      inDanger);    // In danger? false
console.log("Can fight?",      canFight);    // Can fight? true
console.log("Gold earned:",    gold);      // Gold earned: 300  

Go on the quest and explore more about Operators:

Simply JavaScript

Part 22 of 25

JavaScript is a quirky language. To master it, one should know to avoid its hidden traps along with its logic. This series showcase my journey through JS: the pain points, the breakthroughs, and the coding standards that I adopted from my mentors.

Up next

Understanding JavaScript Variables and Data Types Through Game Design

Whenever you start learning a programming language, be it Python, Java, C++, or JavaScript, one concept is common to all of them: variables and data types. Variables and Data Types are the building bl