javascript

examples

examples.js
/**
 * ============================================
 * 2.3 Type Mechanics - Examples
 * ============================================
 *
 * Examples of type coercion, casting, and comparison
 */

// ============================================
// TYPE COERCION - AUTOMATIC CONVERSION
// ============================================

console.log('=== TYPE COERCION ===\n');

// String coercion with + operator
console.log('String Coercion:');
console.log("'5' + 3 =", '5' + 3); // "53"
console.log("'Hello' + true =", 'Hello' + true); // "Hellotrue"
console.log("'Value: ' + null =", 'Value: ' + null); // "Value: null"
console.log("1 + 2 + '3' =", 1 + 2 + '3'); // "33" (left to right)
console.log("'1' + 2 + 3 =", '1' + 2 + 3); // "123"

// Number coercion with other operators
console.log('\nNumber Coercion:');
console.log("'5' - 3 =", '5' - 3); // 2
console.log("'6' * 2 =", '6' * 2); // 12
console.log("'10' / 2 =", '10' / 2); // 5
console.log("'5' % 2 =", '5' % 2); // 1
console.log("+'42' =", +'42'); // 42

// Boolean coercion
console.log('\nBoolean Coercion:');
console.log("!'hello' =", !'hello'); // false
console.log("!'' =", !''); // true
console.log('!0 =', !0); // true
console.log('!1 =', !1); // false
console.log('!null =', !null); // true

// Double negation for boolean conversion
console.log('\nDouble Negation (!!):');
console.log("!!'hello' =", !!'hello'); // true
console.log("!!'' =", !!''); // false
console.log('!!0 =', !!0); // false
console.log('!!1 =', !!1); // true
console.log('!![] =', !![]); // true
console.log('!!{} =', !!{}); // true

// ============================================
// EXPLICIT TYPE CASTING
// ============================================

console.log('\n=== EXPLICIT TYPE CASTING ===\n');

// Converting to String
console.log('To String:');
console.log('String(123) =', String(123));
console.log('String(true) =', String(true));
console.log('String(null) =', String(null));
console.log('String([1,2,3]) =', String([1, 2, 3]));
console.log('(255).toString(16) =', (255).toString(16));
console.log('(255).toString(2) =', (255).toString(2));

// Converting to Number
console.log('\nTo Number:');
console.log("Number('42') =", Number('42'));
console.log("Number('42.5') =", Number('42.5'));
console.log("Number('42px') =", Number('42px')); // NaN
console.log("Number('') =", Number('')); // 0
console.log('Number(true) =', Number(true)); // 1
console.log('Number(false) =', Number(false)); // 0
console.log('Number(null) =', Number(null)); // 0
console.log('Number(undefined) =', Number(undefined)); // NaN

// parseInt and parseFloat
console.log('\nparseInt and parseFloat:');
console.log("parseInt('42') =", parseInt('42'));
console.log("parseInt('42.9') =", parseInt('42.9')); // 42
console.log("parseInt('42px') =", parseInt('42px')); // 42
console.log("parseInt('px42') =", parseInt('px42')); // NaN
console.log("parseInt('1010', 2) =", parseInt('1010', 2)); // 10 (binary)
console.log("parseInt('FF', 16) =", parseInt('FF', 16)); // 255 (hex)
console.log("parseFloat('3.14abc') =", parseFloat('3.14abc')); // 3.14

// Converting to Boolean
console.log('\nTo Boolean:');
console.log('Boolean(1) =', Boolean(1));
console.log('Boolean(0) =', Boolean(0));
console.log("Boolean('') =", Boolean(''));
console.log("Boolean('hello') =", Boolean('hello'));
console.log('Boolean([]) =', Boolean([])); // true!
console.log('Boolean({}) =', Boolean({})); // true!
console.log('Boolean(null) =', Boolean(null));

// ============================================
// TYPEOF OPERATOR
// ============================================

console.log('\n=== TYPEOF OPERATOR ===\n');

console.log('typeof undefined =', typeof undefined);
console.log('typeof null =', typeof null); // "object" (bug!)
console.log('typeof true =', typeof true);
console.log('typeof 42 =', typeof 42);
console.log('typeof 42n =', typeof 42n);
console.log("typeof 'hello' =", typeof 'hello');
console.log('typeof Symbol() =', typeof Symbol());
console.log('typeof {} =', typeof {});
console.log('typeof [] =', typeof []); // "object"
console.log('typeof function(){} =', typeof function () {});
console.log('typeof NaN =', typeof NaN); // "number"

// Better type checking
console.log('\nBetter Type Checking:');
console.log('Array.isArray([]) =', Array.isArray([]));
console.log('Array.isArray({}) =', Array.isArray({}));

function getType(value) {
  if (value === null) return 'null';
  if (Array.isArray(value)) return 'array';
  return typeof value;
}

console.log('getType(null) =', getType(null));
console.log('getType([]) =', getType([]));
console.log('getType({}) =', getType({}));

// ============================================
// INSTANCEOF OPERATOR
// ============================================

console.log('\n=== INSTANCEOF OPERATOR ===\n');

// Arrays
let arr = [1, 2, 3];
console.log('[1,2,3] instanceof Array =', arr instanceof Array);
console.log('[1,2,3] instanceof Object =', arr instanceof Object);

// Functions
function greet() {}
console.log('function instanceof Function =', greet instanceof Function);

// Custom classes
class Person {
  constructor(name) {
    this.name = name;
  }
}

class Employee extends Person {}

let emp = new Employee('John');
console.log('emp instanceof Employee =', emp instanceof Employee);
console.log('emp instanceof Person =', emp instanceof Person);
console.log('emp instanceof Object =', emp instanceof Object);

// Primitives don't work with instanceof
console.log('\nPrimitives with instanceof:');
console.log("'hello' instanceof String =", 'hello' instanceof String); // false
console.log('42 instanceof Number =', 42 instanceof Number); // false

// ============================================
// TRUTHY AND FALSY
// ============================================

console.log('\n=== TRUTHY AND FALSY ===\n');

// The 8 falsy values
console.log('The 8 Falsy Values:');
console.log('Boolean(false) =', Boolean(false));
console.log('Boolean(0) =', Boolean(0));
console.log('Boolean(-0) =', Boolean(-0));
console.log('Boolean(0n) =', Boolean(0n));
console.log("Boolean('') =", Boolean(''));
console.log('Boolean(null) =', Boolean(null));
console.log('Boolean(undefined) =', Boolean(undefined));
console.log('Boolean(NaN) =', Boolean(NaN));

// Surprising truthy values
console.log('\nSurprising Truthy Values:');
console.log("Boolean('0') =", Boolean('0')); // true!
console.log("Boolean('false') =", Boolean('false')); // true!
console.log('Boolean([]) =', Boolean([])); // true!
console.log('Boolean({}) =', Boolean({})); // true!
console.log(
  'Boolean(function(){}) =',
  Boolean(function () {})
); // true!

// Practical examples
console.log('\nPractical Usage:');

// Default values with ||
function greetUser(name) {
  name = name || 'Guest';
  return `Hello, ${name}!`;
}
console.log("greetUser('John') =", greetUser('John'));
console.log("greetUser('') =", greetUser('')); // Uses default
console.log('greetUser(0) =', greetUser(0)); // Uses default (0 is falsy)

// Better: Nullish coalescing (??)
function greetBetter(name) {
  name = name ?? 'Guest';
  return `Hello, ${name}!`;
}
console.log("greetBetter('') =", greetBetter('')); // Empty string kept
console.log('greetBetter(0) =', greetBetter(0)); // 0 kept
console.log('greetBetter(null) =', greetBetter(null)); // Uses default

// ============================================
// EQUALITY COMPARISONS
// ============================================

console.log('\n=== EQUALITY COMPARISONS ===\n');

// Strict equality (===)
console.log('Strict Equality (===):');
console.log('5 === 5 =', 5 === 5); // true
console.log("5 === '5' =", 5 === '5'); // false
console.log('0 === false =', 0 === false); // false
console.log('null === undefined =', null === undefined); // false
console.log('NaN === NaN =', NaN === NaN); // false!

// Loose equality (==)
console.log('\nLoose Equality (==):');
console.log("5 == '5' =", 5 == '5'); // true
console.log('0 == false =', 0 == false); // true
console.log('null == undefined =', null == undefined); // true
console.log("'' == 0 =", '' == 0); // true
console.log("'1' == true =", '1' == true); // true
console.log('[] == false =', [] == false); // true!
console.log('[1] == 1 =', [1] == 1); // true!

// Object.is() - strictest comparison
console.log('\nObject.is():');
console.log('Object.is(5, 5) =', Object.is(5, 5));
console.log("Object.is(5, '5') =", Object.is(5, '5'));
console.log('Object.is(NaN, NaN) =', Object.is(NaN, NaN)); // true!
console.log('Object.is(+0, -0) =', Object.is(+0, -0)); // false!

// Comparing objects
console.log('\nObject Comparison:');
console.log('{} === {} =', {} === {}); // false (different refs)
let obj1 = {};
let obj2 = obj1;
console.log('Same reference === =', obj1 === obj2); // true

// ============================================
// COERCION PUZZLES
// ============================================

console.log('\n=== COERCION PUZZLES ===\n');

console.log('[] + [] =', [] + []); // ""
console.log('[] + {} =', [] + {}); // "[object Object]"
console.log('true + true =', true + true); // 2
console.log('true + false =', true + false); // 1
console.log("'5' + 3 =", '5' + 3); // "53"
console.log("'5' - 3 =", '5' - 3); // 2
console.log('null + 1 =', null + 1); // 1
console.log('undefined + 1 =', undefined + 1); // NaN
console.log("'foo' + + 'bar' =", 'foo' + +'bar'); // "fooNaN"

// ============================================
// BEST PRACTICES
// ============================================

console.log('\n=== BEST PRACTICES ===\n');

// Always use strict equality
console.log('✅ Use === for comparisons');

// Be explicit with type conversions
const userInput = '42';
const number = Number(userInput);
console.log("✅ Explicit: Number('42') =", number);

// Check for NaN properly
const maybeNaN = Number('hello');
console.log('✅ Number.isNaN(NaN) =', Number.isNaN(maybeNaN));
console.log('❌ NaN === NaN =', maybeNaN === maybeNaN);

// Handle null/undefined
const value = null;
console.log('✅ value == null (checks both) =', value == null);
console.log(
  '✅ value === null || value === undefined =',
  value === null || value === undefined
);
Examples - JavaScript Tutorial | DeepML