Skip to content

Commit 36af33c

Browse files
authored
Merge branch 'sudheerj:master' into master
2 parents dd6aeee + 17533ae commit 36af33c

30 files changed

+7286
-4351
lines changed

.github/FUNDING.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github: [sudheerj]
2+
custom: https://buymeacoffee.com/sudheerj

.github/workflows/gen-toc.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Generate table of contents
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
9+
env:
10+
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
11+
12+
jobs:
13+
gen-toc:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v3
18+
with:
19+
ref: ${{ github.head_ref }}
20+
- name: Install dependencies
21+
run: npm install
22+
- name: Generate table of contents
23+
run: npm run gen
24+
- name: 'Commit changes if required'
25+
run: |
26+
if ! git diff --quiet README.md; then
27+
git config user.email "github-actions[bot]@users.noreply.github.com"
28+
git config user.name "GitHub Actions"
29+
git add README.md
30+
git commit -m "[auto] regenerate table of contents"
31+
git push
32+
echo "[info] Table of contents updated and committed."
33+
else
34+
echo "[info] No changes to table of contents."
35+
fi
36+
working-directory: ${{ github.workspace }}

.gitignore

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,134 @@
11
# Cruft
22
.DS_Store
3-
npm-debug.log
4-
.idea
3+
.idea
4+
5+
# Logs
6+
logs
7+
*.log
8+
npm-debug.log*
9+
yarn-debug.log*
10+
yarn-error.log*
11+
lerna-debug.log*
12+
.pnpm-debug.log*
13+
14+
# Diagnostic reports (https://nodejs.org/api/report.html)
15+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16+
17+
# Runtime data
18+
pids
19+
*.pid
20+
*.seed
21+
*.pid.lock
22+
23+
# Directory for instrumented libs generated by jscoverage/JSCover
24+
lib-cov
25+
26+
# Coverage directory used by tools like istanbul
27+
coverage
28+
*.lcov
29+
30+
# nyc test coverage
31+
.nyc_output
32+
33+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34+
.grunt
35+
36+
# Bower dependency directory (https://bower.io/)
37+
bower_components
38+
39+
# node-waf configuration
40+
.lock-wscript
41+
42+
# Compiled binary addons (https://nodejs.org/api/addons.html)
43+
build/Release
44+
45+
# Dependency directories
46+
node_modules/
47+
jspm_packages/
48+
49+
# Snowpack dependency directory (https://snowpack.dev/)
50+
web_modules/
51+
52+
# TypeScript cache
53+
*.tsbuildinfo
54+
55+
# Optional npm cache directory
56+
.npm
57+
58+
# Optional eslint cache
59+
.eslintcache
60+
61+
# Optional stylelint cache
62+
.stylelintcache
63+
64+
# Microbundle cache
65+
.rpt2_cache/
66+
.rts2_cache_cjs/
67+
.rts2_cache_es/
68+
.rts2_cache_umd/
69+
70+
# Optional REPL history
71+
.node_repl_history
72+
73+
# Output of 'npm pack'
74+
*.tgz
75+
76+
# Yarn Integrity file
77+
.yarn-integrity
78+
79+
# dotenv environment variable files
80+
.env
81+
.env.development.local
82+
.env.test.local
83+
.env.production.local
84+
.env.local
85+
86+
# parcel-bundler cache (https://parceljs.org/)
87+
.cache
88+
.parcel-cache
89+
90+
# Next.js build output
91+
.next
92+
out
93+
94+
# Nuxt.js build / generate output
95+
.nuxt
96+
dist
97+
98+
# Gatsby files
99+
.cache/
100+
# Comment in the public line in if your project uses Gatsby and not Next.js
101+
# https://nextjs.org/blog/next-9-1#public-directory-support
102+
# public
103+
104+
# vuepress build output
105+
.vuepress/dist
106+
107+
# vuepress v2.x temp and cache directory
108+
.temp
109+
.cache
110+
111+
# Docusaurus cache and generated files
112+
.docusaurus
113+
114+
# Serverless directories
115+
.serverless/
116+
117+
# FuseBox cache
118+
.fusebox/
119+
120+
# DynamoDB Local files
121+
.dynamodb/
122+
123+
# TernJS port file
124+
.tern-port
125+
126+
# Stores VSCode versions used for testing VSCode extensions
127+
.vscode-test
128+
129+
# yarn v2
130+
.yarn/cache
131+
.yarn/unplugged
132+
.yarn/build-state.yml
133+
.yarn/install-state.gz
134+
.pnp.*

README.md

Lines changed: 5905 additions & 4341 deletions
Large diffs are not rendered by default.
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
function foo() {
2-
let x = y = 0;
3-
x++;
4-
y++;
5-
return x;
2+
let x = (y = 0);
3+
x++;
4+
y++;
5+
return x;
66
}
77

8-
console.log(foo(), typeof x, typeof y);
8+
console.log(foo(), typeof x, typeof y); // 1, undefined, number
9+
10+
/**
11+
* Here's the breakdown:
12+
1. Inside the foo function, x is declared using let, which means it's scoped to the function. However, y is not declared with let or var, so it becomes a global variable.
13+
14+
2. When x = y = 0; is executed, it's interpreted as x = (y = 0);, which initializes y as a global variable with the value of 0, and x as a local variable within the function with the value of 0.
15+
16+
3. x++ increments the local variable x by 1, making it 1.
17+
18+
4. y++ increments the global variable y by 1, making it 1 as well.
19+
20+
5. The function returns the value of x, which is 1.
21+
22+
However, x is scoped within the function, so typeof x outside of the function will result in undefined.
23+
y is a global variable, so typeof y outside of the function will result in number.
24+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
2+
3+
const result = numbers
4+
.filter(num => num % 2 === 0) // [2, 4, 6, 8, 10]
5+
.map(num => num * 2) // [4, 8, 12, 16, 20]
6+
.reduce((sum, num) => sum + num, 0); // 60
7+
8+
console.log(result); // 60
9+
10+
/**
11+
* Explanation:
12+
*
13+
* This demonstrates method chaining with array methods in JavaScript.
14+
*
15+
* 1. filter() creates a new array with elements that pass the test.
16+
* Here, it keeps only even numbers: [2, 4, 6, 8, 10]
17+
*
18+
* 2. map() creates a new array by transforming each element.
19+
* Here, it doubles each number: [4, 8, 12, 16, 20]
20+
*
21+
* 3. reduce() reduces the array to a single value.
22+
* Here, it sums all numbers: 4 + 8 + 12 + 16 + 20 = 60
23+
*
24+
* 4. Each method returns a new array (except reduce), allowing chaining.
25+
*
26+
* 5. This functional programming style is concise and readable.
27+
*
28+
* Note: Each method creates a new array, so for large datasets, consider
29+
* performance implications. A single loop might be more efficient.
30+
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
async function fetchData() {
2+
throw new Error('Network error');
3+
}
4+
5+
async function getData() {
6+
try {
7+
const data = await fetchData();
8+
console.log(data);
9+
return data;
10+
} catch (error) {
11+
console.log('Caught:', error.message);
12+
return null;
13+
}
14+
}
15+
16+
getData().then(result => {
17+
console.log('Result:', result);
18+
});
19+
20+
// Output:
21+
// Caught: Network error
22+
// Result: null
23+
24+
/**
25+
* Explanation:
26+
*
27+
* This demonstrates error handling with async/await in JavaScript.
28+
*
29+
* 1. fetchData() is an async function that throws an error.
30+
*
31+
* 2. In getData(), we use try/catch to handle errors from await fetchData().
32+
*
33+
* 3. When fetchData() throws an error, it's caught by the catch block,
34+
* which logs the error message and returns null.
35+
*
36+
* 4. The .then() receives the return value from getData(), which is null
37+
* because the error was caught and handled.
38+
*
39+
* 5. Without try/catch, the error would propagate and could be caught
40+
* with .catch() on the promise chain.
41+
*/

coding-exercise/closure-counter.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function createCounter() {
2+
let count = 0;
3+
return function() {
4+
count++;
5+
return count;
6+
};
7+
}
8+
9+
const counter1 = createCounter();
10+
const counter2 = createCounter();
11+
12+
console.log(counter1()); // 1
13+
console.log(counter1()); // 2
14+
console.log(counter2()); // 1
15+
console.log(counter1()); // 3
16+
17+
/**
18+
* Explanation:
19+
*
20+
* This demonstrates closure behavior in JavaScript.
21+
*
22+
* 1. createCounter() returns a function that has access to the 'count' variable
23+
* from its outer scope, even after createCounter() has finished executing.
24+
*
25+
* 2. Each call to createCounter() creates a new closure with its own 'count' variable.
26+
* So counter1 and counter2 maintain separate counts.
27+
*
28+
* 3. counter1() increments its own count: 1, 2, 3
29+
* counter2() has its own separate count: 1
30+
*
31+
* This is a classic example of how closures can be used to create private variables.
32+
*/
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Debounce Function
2+
3+
## Challenge
4+
Implement a debounce function that delays the execution of a callback until after a specified delay period has elapsed since the last time it was invoked.
5+
6+
## Problem Description
7+
Debouncing is a programming practice used to ensure that time-consuming tasks do not fire so often. It limits the rate at which a function can fire.
8+
9+
### Real-World Use Cases
10+
- **Search Input**: Wait for the user to stop typing before making an API call
11+
- **Window Resize**: Wait for resize to finish before recalculating layout
12+
- **Scroll Events**: Reduce the number of scroll event handlers fired
13+
- **Button Clicks**: Prevent multiple form submissions
14+
15+
## Example
16+
17+
### Input
18+
```js
19+
function handleSearch(query) {
20+
console.log(`Searching for: ${query}`);
21+
}
22+
23+
const debouncedSearch = debounce(handleSearch, 500);
24+
25+
// User types rapidly
26+
debouncedSearch('J');
27+
debouncedSearch('Ja');
28+
debouncedSearch('Jav');
29+
debouncedSearch('JavaScript');
30+
```
31+
32+
### Output
33+
```
34+
// Only executes once after 500ms of the last call
35+
Searching for: JavaScript
36+
```
37+
38+
## Requirements
39+
1. The debounce function should accept a function and a delay time
40+
2. It should return a new function that delays invoking the original function
41+
3. Each new call should reset the delay timer
42+
4. Only the last call should execute after the delay period
43+
5. The function should preserve the correct `this` context and arguments
44+
45+
## Key Concepts
46+
- **Closures**: Maintaining state (timeoutId) across function calls
47+
- **Higher-Order Functions**: Returning a function from a function
48+
- **setTimeout/clearTimeout**: Managing asynchronous delays
49+
- **Function Context**: Using `apply()` to preserve `this` binding
50+
51+
## Difference from Throttling
52+
- **Debounce**: Executes the function only after the calls have stopped for a specified period
53+
- **Throttle**: Executes the function at most once per specified time interval
54+
55+
## Benefits
56+
- Improves performance by reducing unnecessary function calls
57+
- Reduces API calls and server load
58+
- Provides better user experience by preventing excessive updates

0 commit comments

Comments
 (0)