javascript-interview-prep/lessons/00/knowledge.md

485 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Lesson 00: Getting Started & Assessment Review
**Duration:** 45 minutes
**Objective:** Understand JavaScript fundamentals and identify key areas for focused study
---
## Introduction
Welcome to your JavaScript interview preparation curriculum! This lesson reviews the diagnostic assessment and establishes foundational knowledge that will be built upon in subsequent lessons.
Based on common evaluation results, most developers need focused review in:
- Type coercion and equality
- Closures and scope
- The `this` keyword and context binding
- Prototypes and inheritance
- Modern ES6+ syntax
- Asynchronous execution patterns
---
## Part 1: JavaScript Type System Fundamentals
### 1.1 Primitive Types
JavaScript has 7 primitive types:
```javascript
typeof undefined; // "undefined"
typeof true; // "boolean"
typeof 42; // "number"
typeof 9007199254740991n; // "bigint"
typeof "hello"; // "string"
typeof Symbol(); // "symbol"
typeof null; // "object" ⚠️ This is a bug in JavaScript!
```
**The `null` Bug:**
`typeof null` returning `"object"` is a historical bug that can't be fixed without breaking existing code. `null` represents the intentional absence of any object value.
```javascript
// Checking for null correctly
const value = null;
console.log(value === null); // true
console.log(typeof value === "object" && value === null); // true
```
### 1.2 Reference Types
Objects, Arrays, and Functions are reference types:
```javascript
typeof {}; // "object"
typeof []; // "object" (arrays are objects)
typeof function(){}; // "function"
```
**Key Difference:**
- **Primitives** are compared by value
- **References** are compared by reference (memory location)
```javascript
// Primitives - value comparison
const a = 42;
const b = 42;
console.log(a === b); // true
// References - memory location comparison
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false (different objects in memory)
console.log(arr1 === arr1); // true (same reference)
const arr3 = arr1;
console.log(arr3 === arr1); // true (same reference)
```
---
## Part 2: Floating-Point Precision
### 2.1 The 0.1 + 0.2 Problem
JavaScript uses IEEE 754 double-precision floating-point format. Some decimal numbers cannot be represented exactly in binary.
```javascript
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false ⚠️
```
**Why?**
- 0.1 in binary: `0.0001100110011...` (repeating)
- Computer must round, introducing tiny errors
- These errors accumulate during operations
**Solutions:**
```javascript
// 1. Use epsilon comparison
function areClose(a, b, epsilon = 0.0001) {
return Math.abs(a - b) < epsilon;
}
console.log(areClose(0.1 + 0.2, 0.3)); // true
// 2. Use Number.EPSILON
console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // true
// 3. Work with integers (convert to cents, etc.)
const price1 = 10; // 10 cents
const price2 = 20; // 20 cents
const total = price1 + price2; // 30 cents (exact)
// 4. Round to fixed decimals
const result = Math.round((0.1 + 0.2) * 100) / 100; // 0.3
```
**Interview Tip:** Always mention this caveat when working with money or precise calculations. Suggest using integers or decimal libraries.
---
## Part 3: Var, Let, and Const
### 3.1 The Problem with `var`
```javascript
// Function scope (not block scope)
function example() {
if (true) {
var x = 5;
}
console.log(x); // 5 (var leaks out of the block!)
}
// Hoisting
console.log(y); // undefined (not an error!)
var y = 10;
// What actually happens:
var y;
console.log(y); // undefined
y = 10;
```
**The Classic Loop Problem:**
```javascript
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Logs: 3, 3, 3
// Why? All callbacks share the same 'i' variable
// By the time they execute, the loop finished and i = 3
```
### 3.2 Let and Const (ES6+)
```javascript
// Block scope
if (true) {
let x = 5;
const y = 10;
}
console.log(x); // ReferenceError
console.log(y); // ReferenceError
// No hoisting issues
console.log(z); // ReferenceError (temporal dead zone)
let z = 15;
// Loop with let creates a new binding per iteration
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Logs: 0, 1, 2 ✅
```
**Const Rules:**
```javascript
const x = 10;
x = 20; // TypeError: Assignment to constant variable
// But objects are mutable!
const obj = { name: "Alice" };
obj.name = "Bob"; // ✅ Allowed (modifying property)
obj = {}; // ❌ TypeError (reassigning variable)
// Use Object.freeze() for immutability
const frozen = Object.freeze({ name: "Alice" });
frozen.name = "Bob"; // Silently fails (throws in strict mode)
console.log(frozen.name); // "Alice"
```
**Best Practice:** Use `const` by default, `let` when you need reassignment, avoid `var`.
---
## Part 4: Array Behavior and Holes
### 4.1 Sparse Arrays
```javascript
const arr = [1, 2, 3];
arr[10] = 11;
console.log(arr.length); // 11 (not 4!)
console.log(arr); // [1, 2, 3, empty × 7, 11]
console.log(arr[5]); // undefined (hole in array)
```
**Array Length:**
- Length is always the highest index + 1
- Creating holes doesn't initialize elements
```javascript
const sparse = new Array(5);
console.log(sparse.length); // 5
console.log(sparse[0]); // undefined
console.log(0 in sparse); // false (hole, not undefined value)
const filled = [undefined, undefined];
console.log(0 in filled); // true (actual undefined value)
```
**Array Methods and Holes:**
```javascript
const arr = [1, , 3]; // Array with hole
arr.forEach(x => console.log(x)); // 1, 3 (skips holes)
arr.map(x => x * 2); // [2, empty, 6] (preserves holes)
Array.from(arr); // [1, undefined, 3] (converts holes)
```
---
## Part 5: Type Coercion Essentials
### 5.1 Truthy and Falsy Values
**Falsy values** (8 total):
```javascript
if (false) {} // false
if (0) {} // 0
if (-0) {} // -0
if (0n) {} // 0n (BigInt zero)
if ("") {} // empty string
if (null) {} // null
if (undefined) {} // undefined
if (NaN) {} // NaN
```
Everything else is **truthy**, including:
```javascript
if ("0") {} // truthy (non-empty string)
if ("false") {} // truthy
if ([]) {} // truthy (empty array)
if ({}) {} // truthy (empty object)
if (function(){}) {} // truthy
```
### 5.2 Unary Plus Operator
```javascript
console.log(+"42"); // 42
console.log(+"3.14"); // 3.14
console.log(+"hello"); // NaN
console.log(+true); // 1
console.log(+false); // 0
console.log(+null); // 0
console.log(+undefined); // NaN
// Quick number conversion
const input = "123";
const num = +input; // Same as Number(input)
```
### 5.3 Addition Coercion
```javascript
// String concatenation wins
console.log("" + 1 + 2); // "12" (1 converts to string first)
console.log(1 + 2 + ""); // "3" (addition happens first)
console.log("" + []); // "" (array becomes empty string)
console.log("" + {}); // "[object Object]"
// Arrays
console.log([] + []); // "" (both arrays convert to empty strings)
console.log([1] + [2]); // "12"
console.log([1, 2] + [3]); // "1,23"
```
---
## Part 6: Essential Function Concepts
### 6.1 Function Declarations vs Expressions
```javascript
// Declaration - hoisted
foo(); // ✅ Works
function foo() {
console.log("I'm hoisted!");
}
// Expression - not hoisted
bar(); // ❌ ReferenceError
const bar = function() {
console.log("I'm not hoisted!");
};
```
### 6.2 Arrow Functions Preview
Arrow functions have important differences (covered in Lesson 02):
```javascript
// No 'this' binding
const obj = {
value: 42,
regularFunc: function() {
console.log(this.value); // 42
},
arrowFunc: () => {
console.log(this.value); // undefined (or global value)
}
};
obj.regularFunc(); // 42
obj.arrowFunc(); // undefined
```
**Key Differences:**
- Arrow functions inherit `this` from outer scope
- Cannot be used as constructors
- No `arguments` object
- Cannot use `yield` (not generators)
---
## Part 7: Common Interview Gotchas
### 7.1 Object Property Duplicates
```javascript
const obj = { a: 1, b: 2, a: 3 };
console.log(obj.a); // 3 (last value wins)
```
In modern JavaScript, duplicate keys are allowed. The last value overwrites previous ones.
### 7.2 Automatic Semicolon Insertion (ASI)
```javascript
// This looks fine...
function getData() {
return
{
name: "Alice"
}
}
console.log(getData()); // undefined ⚠️
// JavaScript interprets it as:
function getData() {
return; // semicolon inserted!
{
name: "Alice"
}
}
// Fix: Keep opening brace on same line
function getData() {
return {
name: "Alice"
};
}
```
### 7.3 Implicit Global Variables
```javascript
function oops() {
x = 10; // ⚠️ Creates global variable (no var/let/const)
}
oops();
console.log(x); // 10 (global!)
// Even worse:
let x = y = 10;
// This is really: let x = (y = 10)
// x is local, y is global!
function example() {
let x = y = 20;
}
example();
console.log(y); // 20 (global!)
```
**Fix:** Always use `"use strict";` and declare all variables.
```javascript
"use strict";
function safe() {
x = 10; // ReferenceError: x is not defined
}
```
---
## Part 8: Preparing for Deep Dive Topics
### Topics Covered in Upcoming Lessons
**Lesson 01 - Type System & Coercion:**
- Double equals vs triple equals
- Type conversion rules
- Advanced coercion scenarios
**Lesson 02 - This Binding:**
- How `this` is determined
- Call, apply, and bind
- Arrow functions and `this`
**Lesson 03 - Closures:**
- Lexical scope
- Practical closure patterns
- Memory implications
**Lesson 04 - Event Loop:**
- Call stack, task queue, microtask queue
- Understanding async execution order
**Lesson 05 - Promises:**
- Promise states and chaining
- Error handling
- Async/await patterns
**Lesson 06 - Prototypes:**
- Prototype chain
- Constructor functions vs classes
- Inheritance patterns
**Lesson 07 - ES6+ Features:**
- Destructuring
- Spread/rest operators
- Template literals, default parameters
**Lesson 08 - Array Methods:**
- Map, filter, reduce
- ForEach vs for loops
- Functional programming concepts
---
## Key Takeaways
**Remember:**
1. `typeof null` returns `"object"` (historical bug)
2. Never use `===` with floating-point decimals
3. `var` is function-scoped, `let`/`const` are block-scoped
4. Arrays are compared by reference, not value
5. Use `const` by default, `let` when needed, avoid `var`
6. Arrow functions don't have their own `this` binding
7. Array length = highest index + 1
8. Always declare variables to avoid implicit globals
---
## Practice Tips
1. **Run code examples** - Don't just read them
2. **Predict output** before running code
3. **Understand "why"** - Memorization isn't enough
4. **Practice explaining** concepts out loud
5. **Focus on weak areas** identified in your evaluation
---
## Next Steps
Complete the medium-difficulty quiz to test your understanding of these fundamentals. Then proceed to Lesson 01 to dive deeper into the type system.
**Time to complete quiz:** 10-15 minutes