Closures Questions Javascript

Q1. What will the code print?

let count = 0;
(function printCount() {
	if (count === 0) {
		let count = 1;
		console.log(count); 
	}	
	console.log(count); 
})();

?

Answer

let count = 0;
(function printCount() {
	if (count === 0) {
		let count = 1;
		console.log(count); // 1
	}	
	console.log(count); // 0
})();

Q2. Write a function that would allow you to do as in the following snippet

var addSix = createBase(6);
addSix(10); // prints 16
addSix(21); // prints 27

?

Answer

function createBase(num) {
	return function (a) {
		console.log( num + a );
	}
}

Q3. Time optimization using Closure

function find(index) {
	let a = [];
	for (let i = 0 ; i < 1000000; i++) {
		a[i] = i*i;
	}
	console.log(a[index]);
}

console.time("6");
find(6);
console.timeEnd("6");

console.time("12");
find(12);
console.timeEnd("12");

?

Answer

function find() {
	let a = [];
	for (let i = 0 ; i < 1000000 ; i++) {
		a[i] = i * i;
	}

	return function (index) {
		console.log(a[index]);
	};
}

const closure = find();
console.time("6");
closure(6);
console.timeEnd("6");

console.time("12");
closure(12);
console.timeEnd("12");

Q4. Block scope & setTimeout with closure Output

function a() {
	for (var i = 0 ; i < 3 ; i++) {
		setTimeout(function log() {
			console.log(i); // What is logged?
		}, 1000);
	}
}

a(); 

?

Answer

Followup 1: how will you print // 0, 1, 2

function a() {
	for (var i = 0 ; i < 3 ; i++) {
		setTimeout(function log() {
			console.log(i); // What is logged?
		}, 1000);
	}
}

a(); // ans: 3, 3, 3

Followup 2: how will you print without using let // 0, 1, 2

function a() {
	for (var i = 0 ; i < 3 ; i++) {
		function inner(i) {
			setTimeout(function log() {
				console.log(i); // What is logged?
			}, 1000);
		}

		inner(i);
	}
}

a(); // ans: 3, 3, 3

Q5. How would you use a closure to create a private counter?

?

function counter() {
	var _counter = 0;
	
	function add(increment) {
		_counter += increment;
	}

	function retrive() {
		return "Counter = " + _counter;
	}

	return {
		add,
		retrive,
	};
}

const c = counter();

c.add(5);
c.add(10);
console.log(c.retrive);

Q6. What is a Module Pattern JavaScript?

?

var Module = (function() {
	function privateMethod() {
		// do something
		console.log("Private Method");
	}
	
	return {
		publicMethod; function() {
			// can call privateMethod();	
			console.log("Public Method");
		},
	};
})();

Module.publicMethod(); // Public Method
Module.privateMethod(); // Not a function

Q7. Make this run only once

let view;
function likeTheVideo() {
	view = "Chaitanya";
	console.log("Subscrible to", view);
}

likeTheVideo();
likeTheVideo();
likeTheVideo();
likeTheVideo();

?

Answer

let view;
function likeTheVideo() {
	let called = 0;
	
	return function () {
		if (called > 0) {
			console.log("Already Subscribed to Chaitanya");
		} else {
			view = "Chaitanya";
			console.log("Subscrible to", view);
			called++;
		}
	};
}

let isSubscribed = likeTheVideo();

isSubscribed();
isSubscribed();
isSubscribed();
isSubscribed();

Q8. Once Polyfill, to run a function once provided by lodash

?

function once(func, context) {
	let ran;
	
	return function () {
		if (func) {
			ran = func.apply(context || this, arguments); // Read about apply function
			func = null;
		}

		reutrn ran;
	};
}

const hello = once((a, b) => console.log("Hello", a, b));

hello(1, 2);
hello(1, 2);
hello(1, 2);
hello(1, 2);

Q9. Memoize Polyfill: Implement a Caching/Memoize Function

const clumsysquare = (num1, num2) {
	for (let i = 1; i <= 10000000 ; i++) { }
	
	return num1 * num2;
}

console.time("First Call");
console.log(clumsysquare(9467, 7649));
console.timeEnd("First Call");

console.time("Second Call");
console.log(clumsysquare(9467, 7649));
console.timeEnd("Second Call");

?

Answer

function myMemoize(fn, context) {
	const res = {};
	return function (...args) {
		var argsCache = JSON.stringify(args);

		if (!res[argsCache]) {
			res[argsCache] = fn.call(context || this, ...args)
		} 

		return res[argsCache];
	};
}

const clumsyProduct = (num1, num2) {
	for (let i = 1; i <= 10000000 ; i++) { }
	
	return num1 * num2;
};

const memoizedClumsyProduct = myMemoize(clumsyProduct);

console.time("First Call");
console.log(memoizedClumsyProduct(9467, 7649));
console.timeEnd("First Call");

console.time("Second Call");
console.log(memoizedClumsyProduct(9467, 7649));
console.timeEnd("Second Call");

Q10. Difference between Closure & Scope

?