javascript

examples

examples.js
/**
 * ============================================
 * 3.2 Comparison Operators - Examples
 * ============================================
 */

// ============================================
// 1. EQUALITY OPERATORS OVERVIEW
// ============================================

console.log('=== Equality Operators ===');

// Two types of equality
console.log("5 == '5':", 5 == '5'); // true (loose)
console.log("5 === '5':", 5 === '5'); // false (strict)

console.log('\nSame type, same value:');
console.log('5 === 5:', 5 === 5); // true
console.log("'5' === '5':", '5' === '5'); // true

// ============================================
// 2. LOOSE EQUALITY (==)
// ============================================

console.log('\n=== Loose Equality (==) ===');

// Number and String
console.log('\n--- Number vs String ---');
console.log("5 == '5':", 5 == '5'); // true
console.log("0 == '':", 0 == ''); // true
console.log("0 == '0':", 0 == '0'); // true
console.log("10 == '10.0':", 10 == '10.0'); // true
console.log("42 == '42abc':", 42 == '42abc'); // false

// Boolean conversions
console.log('\n--- Boolean Conversions ---');
console.log('true == 1:', true == 1); // true
console.log('false == 0:', false == 0); // true
console.log("true == '1':", true == '1'); // true
console.log("false == '':", false == ''); // true
console.log("true == 'true':", true == 'true'); // false (NaN)

// null and undefined
console.log('\n--- null and undefined ---');
console.log('null == undefined:', null == undefined); // true
console.log('null == 0:', null == 0); // false
console.log("null == '':", null == ''); // false
console.log('null == false:', null == false); // false
console.log('undefined == 0:', undefined == 0); // false

// Object to primitive
console.log('\n--- Object to Primitive ---');
console.log('[1] == 1:', [1] == 1); // true
console.log("[1,2] == '1,2':", [1, 2] == '1,2'); // true
console.log('[] == 0:', [] == 0); // true
console.log('[] == false:', [] == false); // true

// ============================================
// 3. STRICT EQUALITY (===)
// ============================================

console.log('\n=== Strict Equality (===) ===');

// Different types - always false
console.log("5 === '5':", 5 === '5'); // false
console.log('0 === false:', 0 === false); // false
console.log('null === undefined:', null === undefined); // false
console.log('true === 1:', true === 1); // false

// Same type - compare values
console.log('\n--- Same Type ---');
console.log('5 === 5:', 5 === 5); // true
console.log("'hello' === 'hello':", 'hello' === 'hello'); // true
console.log('true === true:', true === true); // true
console.log('null === null:', null === null); // true

// ============================================
// 4. WHY STRICT EQUALITY IS BETTER
// ============================================

console.log('\n=== Why Use === ===');

// Loose equality surprises
console.log("0 == '':", 0 == ''); // true (unexpected!)
console.log("0 == '0':", 0 == '0'); // true
console.log("'' == '0':", '' == '0'); // false (inconsistent!)

console.log('\nMore surprises:');
console.log("false == '0':", false == '0'); // true
console.log('false == []:', false == []); // true
console.log("[] == '0':", [] == '0'); // false (inconsistent!)

console.log('\nStrict equality - predictable:');
console.log("0 === '':", 0 === ''); // false
console.log("0 === '0':", 0 === '0'); // false
console.log("'' === '0':", '' === '0'); // false

// ============================================
// 5. INEQUALITY OPERATORS
// ============================================

console.log('\n=== Inequality Operators ===');

// Loose inequality (!=)
console.log('--- Loose Inequality (!=) ---');
console.log("5 != '5':", 5 != '5'); // false
console.log('5 != 6:', 5 != 6); // true
console.log('null != undefined:', null != undefined); // false

// Strict inequality (!==)
console.log('\n--- Strict Inequality (!==) ---');
console.log("5 !== '5':", 5 !== '5'); // true
console.log('5 !== 5:', 5 !== 5); // false
console.log('null !== undefined:', null !== undefined); // true

// ============================================
// 6. RELATIONAL OPERATORS
// ============================================

console.log('\n=== Relational Operators ===');

// Greater than, less than
console.log('5 > 3:', 5 > 3); // true
console.log('5 < 3:', 5 < 3); // false
console.log('5 > 5:', 5 > 5); // false

// Greater/less than or equal
console.log('\n--- With Equal ---');
console.log('5 >= 5:', 5 >= 5); // true
console.log('5 >= 3:', 5 >= 3); // true
console.log('5 <= 5:', 5 <= 5); // true
console.log('5 <= 7:', 5 <= 7); // true

// Type coercion in relational operators
console.log('\n--- Type Coercion ---');
console.log("'10' > 5:", '10' > 5); // true
console.log("'10' > '5':", '10' > '5'); // false (string comparison!)
console.log('true > 0:', true > 0); // true (1 > 0)
console.log('false >= 0:', false >= 0); // true (0 >= 0)

// ============================================
// 7. STRING COMPARISON
// ============================================

console.log('\n=== String Comparison ===');

// Lexicographic (dictionary) order
console.log("'a' < 'b':", 'a' < 'b'); // true
console.log("'apple' < 'banana':", 'apple' < 'banana'); // true
console.log("'Apple' < 'apple':", 'Apple' < 'apple'); // true

// String vs Number gotcha
console.log('\n--- String vs Number Gotcha ---');
console.log("'10' < '9':", '10' < '9'); // true (string!)
console.log("'10' < '2':", '10' < '2'); // true (string!)
console.log('10 < 9:', 10 < 9); // false (number)

// Unicode code points
console.log('\n--- Character Codes ---');
console.log("'A'.charCodeAt(0):", 'A'.charCodeAt(0)); // 65
console.log("'Z'.charCodeAt(0):", 'Z'.charCodeAt(0)); // 90
console.log("'a'.charCodeAt(0):", 'a'.charCodeAt(0)); // 97
console.log("'z'.charCodeAt(0):", 'z'.charCodeAt(0)); // 122

// Case-insensitive comparison
console.log('\n--- Case-Insensitive ---');
let str1 = 'Apple';
let str2 = 'apple';
console.log('Case-sensitive:', str1 === str2); // false
console.log('Case-insensitive:', str1.toLowerCase() === str2.toLowerCase()); // true

// ============================================
// 8. OBJECT COMPARISON
// ============================================

console.log('\n=== Object Comparison ===');

// Reference equality
let obj1 = { a: 1 };
let obj2 = { a: 1 };
let obj3 = obj1;

console.log('obj1 === obj2:', obj1 === obj2); // false (different refs)
console.log('obj1 === obj3:', obj1 === obj3); // true (same ref)
console.log('obj1 == obj2:', obj1 == obj2); // false

// Array comparison
console.log('\n--- Array Comparison ---');
let arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];
let arr3 = arr1;

console.log('arr1 === arr2:', arr1 === arr2); // false
console.log('arr1 === arr3:', arr1 === arr3); // true

// Compare content
console.log('\n--- Compare Content ---');
console.log('JSON compare:', JSON.stringify(arr1) === JSON.stringify(arr2)); // true
console.log('toString compare:', arr1.toString() === arr2.toString()); // true

// ============================================
// 9. Object.is() METHOD
// ============================================

console.log('\n=== Object.is() ===');

// Difference from === with NaN
console.log('NaN === NaN:', NaN === NaN); // false
console.log('Object.is(NaN, NaN):', Object.is(NaN, NaN)); // true

// Difference from === with ±0
console.log('\n--- Positive and Negative Zero ---');
console.log('0 === -0:', 0 === -0); // true
console.log('Object.is(0, -0):', Object.is(0, -0)); // false
console.log('Object.is(-0, -0):', Object.is(-0, -0)); // true

// Otherwise same as ===
console.log('\n--- Same as === ---');
console.log('Object.is(5, 5):', Object.is(5, 5)); // true
console.log("Object.is(5, '5'):", Object.is(5, '5')); // false
console.log('Object.is({}, {}):', Object.is({}, {})); // false

// ============================================
// 10. SPECIAL VALUE COMPARISONS
// ============================================

console.log('\n=== Special Values ===');

// NaN
console.log('--- NaN ---');
console.log('NaN == NaN:', NaN == NaN); // false
console.log('NaN === NaN:', NaN === NaN); // false
console.log('NaN != NaN:', NaN != NaN); // true
console.log('Number.isNaN(NaN):', Number.isNaN(NaN)); // true

// null comparisons
console.log('\n--- null Quirks ---');
console.log('null >= 0:', null >= 0); // true
console.log('null <= 0:', null <= 0); // true
console.log('null == 0:', null == 0); // false (!)
console.log('null > 0:', null > 0); // false
console.log('null < 0:', null < 0); // false

// Infinity
console.log('\n--- Infinity ---');
console.log('Infinity > 1000000:', Infinity > 1000000); // true
console.log('Infinity === Infinity:', Infinity === Infinity); // true
console.log('-Infinity < Infinity:', -Infinity < Infinity); // true

// ============================================
// 11. COMPARISON GOTCHAS
// ============================================

console.log('\n=== Gotchas ===');

// Transitivity broken
console.log('--- Transitivity Problem ---');
console.log("'0' == 0:", '0' == 0); // true
console.log("0 == '':", 0 == ''); // true
console.log("'0' == '':", '0' == ''); // false (not transitive!)

// Empty array
console.log('\n--- Empty Array ---');
console.log('[] == false:', [] == false); // true
console.log('[] == 0:', [] == 0); // true
console.log("[] == '':", [] == ''); // true
console.log('[] == []:', [] == []); // false (different refs)

// Array with elements
console.log('\n--- Array with Elements ---');
console.log('[0] == false:', [0] == false); // true
console.log('[1] == true:', [1] == true); // true
console.log('[2] == true:', [2] == true); // false

// ============================================
// 12. PRACTICAL EXAMPLES
// ============================================

console.log('\n=== Practical Examples ===');

// Checking for null or undefined
console.log('--- Null/Undefined Check ---');
function checkValue(value) {
  // Using == for null check (intentional)
  if (value == null) {
    return 'value is null or undefined';
  }
  return 'value is: ' + value;
}
console.log(checkValue(null)); // null or undefined
console.log(checkValue(undefined)); // null or undefined
console.log(checkValue(0)); // value is: 0
console.log(checkValue('')); // value is:

// Safe number comparison
console.log('\n--- Safe Number Comparison ---');
function safeCompare(a, b) {
  if (Number.isNaN(a) || Number.isNaN(b)) {
    return 'Cannot compare: contains NaN';
  }
  if (a === b) return 'equal';
  return a > b ? 'a is greater' : 'b is greater';
}
console.log(safeCompare(5, 3)); // a is greater
console.log(safeCompare(3, 5)); // b is greater
console.log(safeCompare(5, 5)); // equal
console.log(safeCompare(NaN, 5)); // Cannot compare

// Deep equality function
console.log('\n--- Deep Equality ---');
function deepEqual(a, b) {
  if (a === b) return true;
  if (typeof a !== 'object' || typeof b !== 'object') return false;
  if (a === null || b === null) return false;

  let keysA = Object.keys(a);
  let keysB = Object.keys(b);

  if (keysA.length !== keysB.length) return false;

  for (let key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
      return false;
    }
  }
  return true;
}

console.log(deepEqual({ a: 1, b: 2 }, { a: 1, b: 2 })); // true
console.log(deepEqual({ a: 1, b: 2 }, { a: 1, b: 3 })); // false
console.log(deepEqual([1, 2, 3], [1, 2, 3])); // true

// Sorting with comparison
console.log('\n--- Sorting ---');
let numbers = [3, 1, 4, 1, 5, 9, 2, 6];
let sorted = [...numbers].sort((a, b) => a - b);
console.log('Original:', numbers);
console.log('Sorted:', sorted);

let words = ['banana', 'Apple', 'cherry'];
let sortedWords = [...words].sort((a, b) =>
  a.toLowerCase().localeCompare(b.toLowerCase())
);
console.log('Words sorted:', sortedWords);

// ============================================
// 13. COMPARISON CHEAT SHEET
// ============================================

console.log('\n=== Comparison Cheat Sheet ===');

const comparisons = [
  { expr: '5 == "5"', loose: 5 == '5', strict: 5 === '5' },
  { expr: '0 == false', loose: 0 == false, strict: 0 === false },
  { expr: '0 == ""', loose: 0 == '', strict: 0 === '' },
  {
    expr: 'null == undefined',
    loose: null == undefined,
    strict: null === undefined,
  },
  { expr: 'NaN == NaN', loose: NaN == NaN, strict: NaN === NaN },
  { expr: '[] == false', loose: [] == false, strict: [] === false },
  { expr: '[] == []', loose: [] == [], strict: [] === [] },
];

console.log('Expression\t\t== (loose)\t=== (strict)');
console.log('-'.repeat(50));
for (let c of comparisons) {
  console.log(`${c.expr}\t\t${c.loose}\t\t${c.strict}`);
}

console.log('\n=== Examples Complete ===');
Examples - JavaScript Tutorial | DeepML