486 lines
11 KiB
Markdown
486 lines
11 KiB
Markdown
|
|
# 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
|