Q1: Write a function that implements a simple version of Array.prototype.map(). Your function should take an array and a mapping function as inputs and return a new array with the results of applying the mapping function to each element of the input array.
Here's an example of how the function should work:
const inputArray = [1, 2, 3, 4, 5];
const mappingFunction = (x) => x * 2;
const outputArray = customMap(inputArray, mappingFunction);
console.log(outputArray); // Should output: [2, 4, 6, 8, 10]
Your task is to implement the customMap function using JavaScript.
Answer:
Here's a possible implementation of the customMap function:
function customMap(arr, mapFunction) {
const result = [];
for (let i = 0; i < arr.length; i++) {
result.push(mapFunction(arr[i], i, arr));
}
return result;
}
In this implementation, the customMap function takes an array (arr) and a mapping function (mapFunction) as parameters. It iterates through each element of the input array, applies the mapping function to each element, and adds the result to the result array. The mapping function can optionally take three parameters: the current element, the current index, and the original array. This implementation is a simplified version of how the map function works in JavaScript.
Q2: Can you explain what will be logged to the console in the following code snippet?
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
Answer: This code might not behave as one might initially expect. It seems like it should log the numbers 0 to 4 to the console, each after a delay of 1000 milliseconds (1 second). However, due to the asynchronous nature of JavaScript and closures, the output will actually be five instances of the number 5 logged to the console.
Explanation: When the loop runs, it schedules five setTimeout functions to execute after 1000 milliseconds, each with its own closure. However, by the time the first setTimeout function executes, the loop has already finished, and the value of i is 5. Since closures capture references to variables, not their values at the time of creation, all five closures share the same i variable.
So, after 1000 milliseconds, each of the five functions reads the current value of i, which is 5, and logs it to the console. Hence, you will see:
5
5
5
5
5
To achieve the desired behavior of logging numbers 0 to 4 with the corresponding delays, you can use the IIFE (Immediately Invoked Function Expression) technique or ES6's let block scoping in the loop:
Using IIFE:
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(() => {
console.log(j);
}, 1000);
})(i);
}
Using let block scoping:
for (let i = 0; i < 5; i++) {
let j = i; // Create a new variable j in each iteration
setTimeout(() => {
console.log(j);
}, 1000);
}
These approaches will ensure that each closure captures a unique variable with the correct value for the corresponding iteration.
Q3: What is the output?
console.log(1 + '1' - 1);
Answer: The output will be 10. JavaScript coerces the addition operation to concatenate the strings initially, resulting in "11". Then, it performs a subtraction operation converting the string "11" to a number, resulting in 11 - 1 = 10.
Q4: What is a closure?
Answer: A closure refers to a combination of a function (or method) and its lexical environment, within which that function was declared. This allows the function to access variables and parameters from its outer scope even after that outer scope has finished execution.
In simpler terms, a closure "closes" over the lexical scope (variables and methods) from its surrounding context, allowing it to maintain access to those even after the outer function has finished executing.
function outerFunction(outerVariable) {
// Inner function is a closure
return function innerFunction(innerVariable) {
console.log('Outer variable:', outerVariable);
console.log('Inner variable:', innerVariable);
};
}
const closureExample = outerFunction('Hello');
closureExample('World');
// Output: Outer variable: Hello, Inner variable: World
In the above example innerFunction maintain access to variable outerVariable even after outerFunction finished its execution.
Note: The lexical environment
The lexical environment in JavaScript is the set of variables and functions that are accessible to a function at any given point in time.
The lexical environment is created when a function is declared, and it is destroyed when the function exits. The lexical environment of a function consists of the following:
The function's own scope: This contains all of the variables and functions that are declared within the function.
The scope of the function's parent: This contains all of the variables and functions that are declared in the scope where the function is declared.
The global scope: This contains all of the variables and functions that are declared outside of any function.
Q5: What's the difference between null and undefined?
Answer: null represents the intentional absence of any value and is often used to indicate the absence of an object value. undefined typically signifies an uninitialized variable, missing property, or an empty value.
Top comments (4)
The answer to Q4 is incorrect...
Misconceptions About Closures
Jon Randy ποΈ γ» Sep 27
The answer is not wrong. Its correct but its a wide topic there will be a complete blog on it. But here i just give short answer of it.
ok Thanks. I just correct the answer.