can anyone explain to me what is JS doing here? Can anybody explain what is going on here in terms of type coercion, IIFE, and closures?
Function.prototype.toString = (
function() {
const toStringFnRef = Function.prototype.toString;
return function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
)();
console.log(1 + function x() { alert('hi') });
//output: "1start:function x() { alert('hi') }end"
The IIFE is being used to create a local scope where the variable toStringFnRef contains the original value of Function.prototype.toString. Then it redefines this with a function that calls the original function and wraps the result in start: and end.
This could also be done using a lexical block (in ES6 most IIFEs can be refactored like this):
{
const toStringFnRef = Function.prototype.toString;
Function.prototype.toString = function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
When you do 1 + function x() { alert('hi') } it converts both 1 and the function to strings so it can concatenate them. So this calls your redefined Function.prototype.toString(), which surrounds the normal string of the function with those wrappers. This is then concatenated with 1.