When trying to maintain context, like in a setTimeout, I’ve seen lots code that resembles
var self = this;
self is then used inside the timeout to execute the code within the scope of the parent function.
Self is a reserved word in the browser which is equal to Window in most browsers and therefore should not be
overwritten as it could cause confusion for someone thinking self is referring to the window object reference.
In a lot of scenarios you can avoid this completely by refactoring your code to use private functions that are
always in scope. But in the scenarios where you can’t avoid it, it’s better to use a word like “that” which is
not reserved and is commonly used for this purpose, or using Function.prototype.bind to bind the context and
return a function.
PROBLEM:
12345678910111213141516171819202122232425262728
functionMathPrint(){varx=10;vary=100;return{multiply:function(a,b){returna*b;},printToConsole:function(text){console.log(text);},printAndMultiplyAfterWait:function(){setTimeout(function(){this.printToConsole(this.multiply(x,y));},2000);}};}varmathPrint=newMathPrint();console.log(mathPrint.multiply(10,5));//50mathPrint.printToConsole(2000);//2000mathPrint.printAndMultiplyAfterWait();//undefined is not a function}
BAD:
123456789101112131415161718192021222324252627
functionMathPrint(){varx=10;vary=100;//self === windowreturn{multiply:function(a,b){returna*b;},printToConsole:function(text){console.log(text);},printAndMultiplyAfterWait:function(){varself=this;//self -> function scopesetTimeout(function(){self.printToConsole(self.multiply(x,y));},2000);}};}varmathPrint=newMathPrint();console.log(mathPrint.multiply(10,5));//50mathPrint.printToConsole(2000);//2000mathPrint.printAndMultiplyAfterWait();//1000