diff --git a/README.md b/README.md index 6fbbefc..bb5d02b 100644 --- a/README.md +++ b/README.md @@ -3578,10 +3578,12 @@ const { name, age } = { name: 'John', age: 30 }; `Object.freeze()` is used to make an object immutable. Once an object is frozen, you cannot add, remove, or modify its properties. This is useful for creating constants or ensuring that an object remains unchanged throughout the program. -```js +```js live const obj = { name: 'John' }; Object.freeze(obj); obj.name = 'Doe'; // This will not change the name property + +console.log(obj); // { name: 'John' } ``` @@ -5056,8 +5058,8 @@ Here's a table summarizing the 3 client storage mechanisms. To make an HTTP request using the Fetch API, you can use the `fetch` function, which returns a promise. You can handle the response using `.then()` and `.catch()` for error handling. Here's a basic example of a GET request: -```js -fetch('https://api.example.com/data') +```js live +fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error('Error:', error)); @@ -5065,13 +5067,17 @@ fetch('https://api.example.com/data') For a POST request, you can pass an options object as the second argument to `fetch`: -```js -fetch('https://api.example.com/data', { +```js live +fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', + body: JSON.stringify({ + title: 'foo', + body: 'bar', + userId: 1, + }), headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json; charset=UTF-8', }, - body: JSON.stringify({ key: 'value' }), }) .then((response) => response.json()) .then((data) => console.log(data)) diff --git a/questions/can-you-offer-a-use-case-for-the-new-arrow-function-syntax-how-does-this-new-syntax-differ-from-other-functions/en-US.mdx b/questions/can-you-offer-a-use-case-for-the-new-arrow-function-syntax-how-does-this-new-syntax-differ-from-other-functions/en-US.mdx index 2fca734..93a71c8 100644 --- a/questions/can-you-offer-a-use-case-for-the-new-arrow-function-syntax-how-does-this-new-syntax-differ-from-other-functions/en-US.mdx +++ b/questions/can-you-offer-a-use-case-for-the-new-arrow-function-syntax-how-does-this-new-syntax-differ-from-other-functions/en-US.mdx @@ -76,7 +76,7 @@ console.log(doubled); // [2, 4, 6, 8, 10] Arrow functions can be used in event handlers to maintain the `this` context of the class or object. -```js +```js live class Button { constructor() { this.count = 0; @@ -84,13 +84,15 @@ class Button { this.button.innerText = 'Click me'; this.button.addEventListener('click', () => { this.count++; - console.log(this.count); + console.log('count:', this.count); }); document.body.appendChild(this.button); } } -const button = new Button(); +const myButton = new Button(); +myButton.button.click(); // count: 1 +myButton.button.click(); // count: 2 ``` ## Further reading diff --git a/questions/explain-hoisting/en-US.mdx b/questions/explain-hoisting/en-US.mdx index a2004a9..6a317c6 100644 --- a/questions/explain-hoisting/en-US.mdx +++ b/questions/explain-hoisting/en-US.mdx @@ -41,7 +41,7 @@ Let's explain with a few code samples. Note that the code for these examples sho Hoisting is seen in action here as even though `foo` is declared and initialized after the first `console.log()`, the first `console.log()` prints the value of `foo` as `undefined`. -```js +```js live console.log(foo); // undefined var foo = 1; console.log(foo); // 1 @@ -49,7 +49,7 @@ console.log(foo); // 1 You can visualize the code as: -```js +```js live var foo; console.log(foo); // undefined foo = 1; @@ -60,17 +60,17 @@ console.log(foo); // 1 Variables declared via `let`, `const`, and `class` are hoisted as well. However, unlike `var` and `function`, they are not initialized and accessing them before the declaration will result in a `ReferenceError` exception. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed. -```js +```js live y; // ReferenceError: Cannot access 'y' before initialization let y = 'local'; ``` -```js +```js live z; // ReferenceError: Cannot access 'z' before initialization const z = 'local'; ``` -```js +```js live Foo; // ReferenceError: Cannot access 'Foo' before initialization class Foo { @@ -82,7 +82,7 @@ class Foo { Function expressions are functions written in the form of variable declarations. Since they are also declared using `var`, only the variable declaration is hoisted. -```js +```js live console.log(bar); // undefined bar(); // Uncaught TypeError: bar is not a function @@ -95,7 +95,7 @@ var bar = function () { Function declarations use the `function` keyword. Unlike function expressions, function declarations have both the declaration and definition hoisted, thus they can be called even before they are declared. -```js +```js live console.log(foo); // [Function: foo] foo(); // 'FOOOOO' diff --git a/questions/explain-the-concept-of-this-binding-in-event-handlers/en-US.mdx b/questions/explain-the-concept-of-this-binding-in-event-handlers/en-US.mdx index 9322966..3821e4a 100644 --- a/questions/explain-the-concept-of-this-binding-in-event-handlers/en-US.mdx +++ b/questions/explain-the-concept-of-this-binding-in-event-handlers/en-US.mdx @@ -18,10 +18,17 @@ In JavaScript, the `this` keyword is a reference to the object that is currently In the context of event handlers, `this` usually refers to the DOM element that triggered the event. For example: -```js +```js live +// Create a button element and append it to the DOM +const button = document.createElement('button'); +button.id = 'myButton'; +document.body.appendChild(button); + document.getElementById('myButton').addEventListener('click', function () { - console.log(this); // Logs the button element + console.log(this); // `this` refers to the 'myButton' element }); + +button.click(); // Logs the button element ``` In this example, `this` inside the event handler refers to the button element that was clicked. @@ -34,7 +41,12 @@ There are several ways to change the value of `this` in event handlers: The `bind()` method creates a new function that, when called, has its `this` keyword set to the provided value: -```js +```js live +// Create a button element and append it to the DOM +const button = document.createElement('button'); +button.id = 'myButton'; +document.body.appendChild(button); + function handleClick() { console.log(this); // Logs the object passed to bind() } @@ -43,6 +55,8 @@ const obj = { name: 'MyObject' }; document .getElementById('myButton') .addEventListener('click', handleClick.bind(obj)); + +button.click(); // Logs obj because handleClick was bound to obj using bind() ``` In this example, `this` inside `handleClick` refers to `obj`. @@ -51,7 +65,12 @@ In this example, `this` inside `handleClick` refers to `obj`. Arrow functions do not have their own `this` context; they inherit `this` from the surrounding lexical context: -```js +```js live +// Create a button element and append it to the DOM +const button = document.createElement('button'); +button.id = 'myButton'; +document.body.appendChild(button); + const obj = { name: 'MyObject', handleClick: function () { @@ -62,6 +81,7 @@ const obj = { }; obj.handleClick(); +button.click(); // This will log obj ``` In this example, `this` inside the arrow function refers to `obj`. @@ -70,7 +90,12 @@ In this example, `this` inside the arrow function refers to `obj`. You can also assign the context explicitly by using a variable: -```js +```js live +// Create a button element and append it to the DOM +const button = document.createElement('button'); +button.id = 'myButton'; +document.body.appendChild(button); + const obj = { name: 'MyObject', handleClick: function () { @@ -82,6 +107,7 @@ const obj = { }; obj.handleClick(); +button.click(); // This will log obj ``` In this example, `self` is used to capture the value of `this` from the outer function. diff --git a/questions/how-can-you-avoid-problems-related-to-hoisting/en-US.mdx b/questions/how-can-you-avoid-problems-related-to-hoisting/en-US.mdx index f6ea850..31d9d51 100644 --- a/questions/how-can-you-avoid-problems-related-to-hoisting/en-US.mdx +++ b/questions/how-can-you-avoid-problems-related-to-hoisting/en-US.mdx @@ -56,7 +56,7 @@ function example() { // Now use a and b console.log(a + b); } -example(); +example(); // Output: 3 ``` ### Declare functions before calling them diff --git a/questions/how-do-you-make-an-http-request-using-the-fetch-api/en-US.mdx b/questions/how-do-you-make-an-http-request-using-the-fetch-api/en-US.mdx index b633f02..b86ca9f 100644 --- a/questions/how-do-you-make-an-http-request-using-the-fetch-api/en-US.mdx +++ b/questions/how-do-you-make-an-http-request-using-the-fetch-api/en-US.mdx @@ -6,8 +6,8 @@ title: How do you make an HTTP request using the Fetch API? To make an HTTP request using the Fetch API, you can use the `fetch` function, which returns a promise. You can handle the response using `.then()` and `.catch()` for error handling. Here's a basic example of a GET request: -```js -fetch('https://api.example.com/data') +```js live +fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error('Error:', error)); @@ -15,13 +15,17 @@ fetch('https://api.example.com/data') For a POST request, you can pass an options object as the second argument to `fetch`: -```js -fetch('https://api.example.com/data', { +```js live +fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', + body: JSON.stringify({ + title: 'foo', + body: 'bar', + userId: 1, + }), headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json; charset=UTF-8', }, - body: JSON.stringify({ key: 'value' }), }) .then((response) => response.json()) .then((data) => console.log(data)) @@ -36,8 +40,8 @@ fetch('https://api.example.com/data', { To make a basic GET request, you can use the `fetch` function with the URL of the resource you want to fetch. The `fetch` function returns a promise that resolves to the `Response` object representing the response to the request. -```js -fetch('https://api.example.com/data') +```js live +fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => { if (!response.ok) { throw new Error('Network response was not ok'); @@ -52,8 +56,8 @@ fetch('https://api.example.com/data') The `Response` object has several methods to handle different types of responses, such as `.json()`, `.text()`, `.blob()`, and `.arrayBuffer()`. -```js -fetch('https://api.example.com/data') +```js live +fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => response.text()) .then((text) => console.log(text)) .catch((error) => console.error('Error:', error)); @@ -63,13 +67,17 @@ fetch('https://api.example.com/data') To make a POST request, you need to pass an options object as the second argument to `fetch`. This object can include the HTTP method, headers, and body of the request. -```js -fetch('https://api.example.com/data', { +```js live +fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', + body: JSON.stringify({ + title: 'foo', + body: 'bar', + userId: 1, + }), headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json; charset=UTF-8', }, - body: JSON.stringify({ key: 'value' }), }) .then((response) => { if (!response.ok) { @@ -85,8 +93,8 @@ fetch('https://api.example.com/data', { Error handling in the Fetch API can be done using the `.catch()` method. It's also a good practice to check the `response.ok` property to ensure the request was successful. -```js -fetch('https://api.example.com/data') +```js live +fetch('https://jsonplaceholder.tyicode.com/posts/1/comments') // Typo in the URL .then((response) => { if (!response.ok) { throw new Error('Network response was not ok'); @@ -101,10 +109,12 @@ fetch('https://api.example.com/data') You can also use the Fetch API with `async/await` for a more synchronous-looking code. -```js +```js live async function fetchData() { try { - const response = await fetch('https://api.example.com/data'); + const response = await fetch( + 'https://jsonplaceholder.typicode.com/todos/1', + ); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/questions/what-are-callback-functions-and-how-are-they-used/en-US.mdx b/questions/what-are-callback-functions-and-how-are-they-used/en-US.mdx index 12c0811..1ba2261 100644 --- a/questions/what-are-callback-functions-and-how-are-they-used/en-US.mdx +++ b/questions/what-are-callback-functions-and-how-are-they-used/en-US.mdx @@ -52,7 +52,7 @@ greet('Alice', sayGoodbye); Asynchronous callbacks are used for operations that take some time to complete, such as reading files, making HTTP requests, or handling events. These callbacks are executed after the asynchronous operation has finished. -```js +```js live function fetchData(callback) { setTimeout(() => { const data = { name: 'John Doe' }; @@ -65,6 +65,7 @@ function handleData(data) { } fetchData(handleData); +// Output: { name: 'John Doe' } after 1 second ``` ### Common use cases @@ -73,19 +74,25 @@ fetchData(handleData); Callbacks are often used in event handling. For example, in JavaScript, you can pass a callback function to an event listener. -```js -document.getElementById('myButton').addEventListener('click', function () { - console.log('Button clicked!'); +```js live +const button = document.createElement('button'); + +button.addEventListener('click', () => { + setTimeout(() => { + console.log('Button clicked after 1s'); + }, 1000); }); + +button.click(); ``` #### API calls Callbacks are frequently used in making API calls to handle the response data. -```js +```js live function getUserData(userId, callback) { - fetch(`https://api.example.com/users/${userId}`) + fetch(`https://jsonplaceholder.typicode.com/todos/2`) .then((response) => response.json()) .then((data) => callback(data)) .catch((error) => console.error('Error:', error)); @@ -102,7 +109,7 @@ getUserData(1, displayUserData); Callbacks are also used with timers like `setTimeout` and `setInterval`. -```js +```js live function sayHello() { console.log('Hello, world!'); } diff --git a/questions/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue/en-US.mdx b/questions/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue/en-US.mdx index dc7d7e9..20bfdb8 100644 --- a/questions/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue/en-US.mdx +++ b/questions/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue/en-US.mdx @@ -67,7 +67,7 @@ Microtasks are tasks that have a higher priority than macrotasks and are execute The following code logs some statements using a combination of normal execution, macrotasks, and microtasks. -```js +```js live console.log('Start'); setTimeout(() => { diff --git a/questions/what-is-objectfreeze-for/en-US.mdx b/questions/what-is-objectfreeze-for/en-US.mdx index 3e6cfc0..aca3ab8 100644 --- a/questions/what-is-objectfreeze-for/en-US.mdx +++ b/questions/what-is-objectfreeze-for/en-US.mdx @@ -6,10 +6,12 @@ title: What is `Object.freeze()` for? `Object.freeze()` is used to make an object immutable. Once an object is frozen, you cannot add, remove, or modify its properties. This is useful for creating constants or ensuring that an object remains unchanged throughout the program. -```js +```js live const obj = { name: 'John' }; Object.freeze(obj); obj.name = 'Doe'; // This will not change the name property + +console.log(obj); // { name: 'John' } ``` --- @@ -22,7 +24,7 @@ obj.name = 'Doe'; // This will not change the name property To use `Object.freeze()`, simply pass the object you want to freeze as an argument to the method. Here is a basic example: -```js +```js live const obj = { name: 'John', age: 30, @@ -54,7 +56,7 @@ console.log(obj); // Output: { name: "John", age: 30 } - `Object.freeze()` only makes the object itself immutable. If the object contains nested objects, those nested objects are not frozen and can still be modified. - To deeply freeze an object, you would need to recursively apply `Object.freeze()` to all nested objects. -```js +```js live const deepFreeze = (obj) => { Object.keys(obj).forEach((key) => { if (typeof obj[key] === 'object' && obj[key] !== null) { diff --git a/questions/what-is-the-definition-of-a-higher-order-function/en-US.mdx b/questions/what-is-the-definition-of-a-higher-order-function/en-US.mdx index c1ac02b..7c6dcdd 100644 --- a/questions/what-is-the-definition-of-a-higher-order-function/en-US.mdx +++ b/questions/what-is-the-definition-of-a-higher-order-function/en-US.mdx @@ -97,7 +97,10 @@ function add(a, b) { } const loggedAdd = withLogging(add); -console.log(loggedAdd(2, 3)); // Output: Calling add with arguments [2, 3] 5 +console.log(loggedAdd(2, 3)); +// Output: +// Calling add with arguments [2, 3] +// 5 ``` The `withLogging` function is a higher-order function that takes a function fn as an argument and returns a new function that logs the function call before executing the original function diff --git a/questions/what-is-the-dom-and-how-is-it-structured/en-US.mdx b/questions/what-is-the-dom-and-how-is-it-structured/en-US.mdx index 7091dde..85971b8 100644 --- a/questions/what-is-the-dom-and-how-is-it-structured/en-US.mdx +++ b/questions/what-is-the-dom-and-how-is-it-structured/en-US.mdx @@ -67,12 +67,15 @@ JavaScript can be used to access and manipulate the DOM. Here are some common me Example: -```js -// Select the