Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions code-examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# JavaScript Concept Code Examples

This directory contains practical code examples for the 33 JavaScript concepts every developer should know. These examples are designed to help you understand and practice each concept with hands-on code.

## Purpose

The main repository provides comprehensive explanations of JavaScript concepts with articles and videos. This directory supplements that content by providing:

- Practical code examples for each concept
- Interactive demonstrations of JavaScript behavior
- Clear explanations of complex concepts through code
- Reference implementations for learning

## Available Examples

- `call-stack-example.js` - Demonstrates how the JavaScript call stack works
- `primitive-types-example.js` - Shows examples of JavaScript's primitive data types
- `value-reference-types-example.js` - Illustrates the difference between value and reference types
- `implicit-explicit-typing-example.js` - Shows implicit and explicit type coercion in JavaScript

## How to Use

Run any example file with Node.js:

```bash
node code-examples/call-stack-example.js
```

Each file is self-contained and includes detailed comments explaining the concepts being demonstrated.

## Contributing

Feel free to add more examples for the remaining concepts:

1. Create a new file following the naming pattern: `{concept-name}-example.js`
2. Include detailed comments explaining the concept
3. Provide practical examples that demonstrate the concept in action
4. Test your example with Node.js before submitting a PR

## License

This project is licensed under the MIT License - see the LICENSE file for details.
57 changes: 57 additions & 0 deletions code-examples/call-stack-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Call Stack Example
*
* The call stack is a mechanism that the JavaScript interpreter uses to keep track of function execution within a program.
* It follows the Last In, First Out (LIFO) principle.
*/

console.log('1. Script execution starts');

function firstFunction() {
console.log('3. Inside firstFunction');
secondFunction();
console.log('5. Back to firstFunction');
}

function secondFunction() {
console.log('4. Inside secondFunction');
}

// Execution starts here
firstFunction();
console.log('6. Script execution ends');

/*
* Call Stack Visualization:
*
* At each step, the call stack looks like this:
*
* Step 1: console.log('1. Script execution starts') -> []
* Step 2: firstFunction() -> [firstFunction]
* Step 3: console.log('3. Inside firstFunction') -> [firstFunction]
* Step 4: secondFunction() -> [firstFunction, secondFunction]
* Step 5: console.log('4. Inside secondFunction') -> [firstFunction, secondFunction]
* Step 6: secondFunction() returns -> [firstFunction]
* Step 7: console.log('5. Back to firstFunction') -> [firstFunction]
* Step 8: firstFunction() returns -> []
* Step 9: console.log('6. Script execution ends') -> []
*/

// Example of call stack with recursion
function factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1); // This creates multiple stack frames
}

console.log('Factorial of 5:', factorial(5));

// Example of call stack overflow
function stackOverflow() {
console.log('This will cause a stack overflow');
stackOverflow(); // Recursive call without termination condition
}

// Uncomment the next line to see the stack overflow error
// stackOverflow();
210 changes: 210 additions & 0 deletions code-examples/implicit-explicit-typing-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/**
* Implicit, Explicit, Nominal, Structuring and Duck Typing Example
*
* JavaScript is dynamically typed with various typing approaches:
* - Implicit Typing (Type Coercion): JavaScript automatically converts types
* - Explicit Typing: Manual conversion using functions like Number(), String(), Boolean()
* - Duck Typing: If it walks like a duck and quacks like a duck, it's a duck
*/

// Implicit Typing (Type Coercion) examples
console.log("=== Implicit Typing (Type Coercion) ===");

// String concatenation with number
let result1 = "5" + 3; // "53" (number 3 is converted to string)
console.log('"5" + 3 =', result1, typeof result1); // "53" string

// Arithmetic operation with string
let result2 = "10" - 5; // 5 (string "10" is converted to number)
console.log('"10" - 5 =', result2, typeof result2); // 5 number

// Boolean conversion in conditionals
let result3 = "hello" && 42; // 42 (non-empty string is truthy)
console.log('"hello" && 42 =', result3); // 42

let result4 = "" && 42; // "" (empty string is falsy)
console.log('"" && 42 =', result4); // ""

// Loose equality comparison
console.log('5 == "5":', 5 == "5"); // true (values are converted before comparison)
console.log('0 == false:', 0 == false); // true (both convert to 0)
console.log('null == undefined:', null == undefined); // true (special case)

// Strict equality comparison
console.log('5 === "5":', 5 === "5"); // false (no type conversion)
console.log('0 === false:', 0 === false); // false (different types)

// Explicit Typing examples
console.log("\n=== Explicit Typing ===");

// Converting to number
let strNum = "42";
let num = Number(strNum);
console.log('Number("42"):', num, typeof num); // 42 number

let parsedNum = parseInt("42.7");
console.log('parseInt("42.7"):', parsedNum, typeof parsedNum); // 42 number

let floatNum = parseFloat("42.7");
console.log('parseFloat("42.7"):', floatNum, typeof floatNum); // 42.7 number

// Converting to string
let numToConvert = 123;
let str = String(numToConvert);
console.log('String(123):', str, typeof str); // "123" string

let boolToConvert = true;
let strBool = boolToConvert.toString();
console.log('true.toString():', strBool, typeof strBool); // "true" string

// Converting to boolean
let truthyValue = Boolean("hello");
console.log('Boolean("hello"):', truthyValue, typeof truthyValue); // true boolean

let falsyValue = Boolean(0);
console.log('Boolean(0):', falsyValue, typeof falsyValue); // false boolean

// Duck Typing examples
console.log("\n=== Duck Typing ===");

// Objects with similar interfaces can be used interchangeably
function makeSound(animal) {
// Duck typing: if it has a makeSound method, treat it as an animal
if (typeof animal.makeSound === 'function') {
animal.makeSound();
} else {
console.log("This animal doesn't know how to make a sound");
}
}

// Different objects with the same interface (duck typing)
let dog = {
name: "Rex",
makeSound: function() {
console.log("Woof!");
}
};

let cat = {
name: "Whiskers",
makeSound: function() {
console.log("Meow!");
}
};

let robot = {
name: "Robo",
makeSound: function() {
console.log("Beep!");
}
};

// All can be used with the same function due to duck typing
makeSound(dog); // Woof!
makeSound(cat); // Meow!
makeSound(robot); // Beep!

// Array-like object (duck typing)
let arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
// Add a method that works with array-like objects
forEach: function(callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
}
};

console.log("Array-like object:");
arrayLike.forEach(item => console.log(item)); // 'a', 'b', 'c'

// Structural Typing (objects are compatible if they share the same structure)
console.log("\n=== Structural Typing ===");

// Functions that expect objects with specific structure
function printName(person) {
console.log(`Name: ${person.name}`);
}

// Objects with the same structure can be used interchangeably
let person1 = {
name: "Alice",
age: 30
};

let person2 = {
name: "Bob",
occupation: "Developer"
};

let person3 = {
name: "Charlie",
height: 180
};

// All of these work because they have the 'name' property
printName(person1); // Name: Alice
printName(person2); // Name: Bob
printName(person3); // Name: Charlie

// Falsy and truthy values conversion
console.log("\n=== Falsy and Truthy Values ===");

let values = [0, -0, "", "hello", null, undefined, NaN, [], [1, 2], {}, {a: 1}, false, true];

values.forEach(value => {
console.log(`${JSON.stringify(value)} is ${Boolean(value) ? 'truthy' : 'falsy'} (type: ${typeof value})`);
});

// Complex coercion examples
console.log("\n=== Complex Coercion Examples ===");

// Comparing arrays
console.log('[1, 2, 3] == [1, 2, 3]:', [1, 2, 3] == [1, 2, 3]); // false (different objects)
console.log('[1, 2, 3] === [1, 2, 3]:', [1, 2, 3] === [1, 2, 3]); // false (different objects)

// Comparing objects
let obj1 = { a: 1 };
let obj2 = { a: 1 };
console.log('obj1 == obj2:', obj1 == obj2); // false (different objects in memory)
console.log('obj1 === obj2:', obj1 === obj2); // false (different objects in memory)

// Comparing same object reference
let obj3 = obj1;
console.log('obj1 == obj3:', obj1 == obj3); // true (same object in memory)
console.log('obj1 === obj3:', obj1 === obj3); // true (same object in memory)

// Comparing with valueOf and toString
let objA = {
valueOf: function() { return 42; },
toString: function() { return "forty-two"; }
};

let objB = {
valueOf: function() { return 42; },
toString: function() { return "forty-two"; }
};

console.log('objA == 42:', objA == 42); // true (objA.valueOf() is called)
console.log('objA == "forty-two":', objA == "forty-two"); // true (objA.toString() is called in some contexts)

// Demonstration of truthiness in conditional contexts
console.log("\n=== Truthiness in Conditionals ===");

let valueToCheck = "hello";
if (valueToCheck) {
console.log("String 'hello' is truthy, so this runs");
}

let emptyString = "";
if (!emptyString) {
console.log("Empty string is falsy, so this runs");
}

let zero = 0;
if (!zero) {
console.log("Zero is falsy, so this runs");
}
75 changes: 75 additions & 0 deletions code-examples/primitive-types-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* Primitive Types Example
*
* JavaScript has six primitive data types: string, number, bigint, boolean, undefined, and symbol.
* There's also a special primitive type called null, which represents the intentional absence of any object value.
* These types are immutable, meaning their values cannot be altered.
*/

// String primitive type
let name = "JavaScript";
console.log("String:", name, "Type:", typeof name);

// Number primitive type
let age = 25;
console.log("Number:", age, "Type:", typeof age);

// BigInt primitive type
let bigNumber = 123456789012345678901234567890n;
console.log("BigInt:", bigNumber, "Type:", typeof bigNumber);

// Boolean primitive type
let isLearning = true;
console.log("Boolean:", isLearning, "Type:", typeof isLearning);

// Undefined primitive type
let notDefined;
console.log("Undefined:", notDefined, "Type:", typeof notDefined);

// Symbol primitive type
let symbol1 = Symbol('description');
let symbol2 = Symbol('description');
console.log("Symbol 1:", symbol1, "Type:", typeof symbol1);
console.log("Symbol 2:", symbol2, "Are they equal?", symbol1 === symbol2); // false, symbols are always unique

// Null primitive type
let emptyValue = null;
console.log("Null:", emptyValue, "Type:", typeof emptyValue); // Note: typeof null returns "object" (this is a historical bug in JavaScript)

// Demonstrating immutability of primitives
let originalString = "Hello";
let modifiedString = originalString.toUpperCase(); // Creates a new string

console.log("Original:", originalString); // Still "Hello"
console.log("Modified:", modifiedString); // "HELLO"

// Primitive values are copied by value, not by reference
let a = 10;
let b = a; // b gets a copy of the value
b = 20; // Changing b doesn't affect a

console.log("a:", a); // Still 10
console.log("b:", b); // 20

// Primitive types don't have properties or methods, but JavaScript temporarily wraps them with objects when needed
console.log("Length of string:", name.length); // JavaScript temporarily wraps the string primitive in a String object to access the length property

// Example of how primitives are immutable
let greeting = "Hello";
greeting[0] = "h"; // This operation has no effect on the original string
console.log("Greeting after trying to modify:", greeting); // Still "Hello", not "hello"

// Demonstrating automatic wrapping with String object when calling methods
let upperGreeting = greeting.toUpperCase(); // JavaScript wraps greeting in String object to call toUpperCase()
console.log("Uppercase greeting:", upperGreeting); // "HELLO"

// Different ways to create primitives vs objects
let primitiveStr = "Hello"; // String primitive
let objectStr = new String("Hello"); // String object

console.log("Primitive:", primitiveStr, "Type:", typeof primitiveStr); // "Hello", "string"
console.log("Object:", objectStr, "Type:", typeof objectStr); // String object, "object"

// Equality comparison
console.log("Are they equal?", primitiveStr == objectStr); // true (loose equality)
console.log("Are they strictly equal?", primitiveStr === objectStr); // false (strict equality)
Loading