Skip to content

loopFunctions

Reports function declarations and expressions inside loops that reference variables modified by the loop.

✅ This rule is included in the performance logical presets.

Creating functions inside loops that reference variables modified by the loop often leads to unexpected behavior. Functions created in this way share the same scope and capture references to loop variables rather than their values at creation time. This means all created functions typically reference the final value of the loop variable, not the value during their creation.

This behavior is a common source of bugs in JavaScript applications, especially when creating event handlers, callbacks, or other deferred operations within loops.

AEconsB0handleAE< =sp ansty="le--0:#D6DEEB;--1:#403F">53 [<];d ivclassNa="meec-li">AEf53< (sp ansty="le--0:#C792EA;--1:#8844">AEle5<3isp ansty="le--0:#C792EA;--1:#8844">AE <= sp ansty="le--0:#F78C6C;--1:#AA09">8<20sp ansty="le--0:#D6DEEB;--1:#403F">53; A5<3 sp ansty="le--0:#F78C6C;--1:#AA09">8<25sp ansty="le--0:#D6DEEB;--1:#403F">53;< isp ansty="le--0:#C792EA;--1:#8844">AE<++sp ansty="le--0:#D6DEEB;--1:#403F">53)< {d ivclassNa="meec-li">53< sp ansty="le--0:#D6DEEB;--1:#403F">53handleAB0pu5<3(sp ansty="le--0:#C792EA;--1:#8844">AEfuncti5<3 sp ansty="le--0:#D9F5DD;--1:#1111">11<()sp ansty="le--0:#D6DEEB;--1:#403F">53< {d ivclassNa="meec-li">nt < sp ansty="le--0:#C792EA;--1:#8844">AEretu53 53< sp ansty="le--0:#D6DEEB;--1:#403F">53}<);d ivclassNa="meec-li">5<3}d ivclassNa="meec-li">76// All handlers return 5, not 0, 1, 2, 3,< 4d ivclassNa="meco">< 4d>AEconsB0iteAE< =sp ansty="le--0:#D6DEEB;--1:#403F">53< [sp ansty="le--0:#D9F5DD;--1:#1111">1<1"sp ansty="le--0:#ECC48D;--1:#984E">41<1"sp ansty="le--0:#D6DEEB;--1:#403F">53<, sp ansty="le--0:#D9F5DD;--1:#1111">1<1"sp ansty="le--0:#ECC48D;--1:#984E">41<1"sp ansty="le--0:#D6DEEB;--1:#403F">53<, sp ansty="le--0:#D9F5DD;--1:#1111">1<1"sp ansty="le--0:#ECC48D;--1:#984E">41<1"sp ansty="le--0:#D6DEEB;--1:#403F">53<];d ivclassNa="meec-li">AEf53< (sp ansty="le--0:#C792EA;--1:#8844">AEle5<3isp ansty="le--0:#C792EA;--1:#8844">AE <= sp ansty="le--0:#F78C6C;--1:#AA09">8<20sp ansty="le--0:#D6DEEB;--1:#403F">53; A53 iteA72leng53;< isp ansty="le--0:#C792EA;--1:#8844">AE<++sp ansty="le--0:#D6DEEB;--1:#403F">53)< {d ivclassNa="meec-li">53< sp ansty="le--0:#D6DEEB;--1:#403F">53buttAB0addEventListen5<3(sp ansty="le--0:#D9F5DD;--1:#1111">1<1"sp ansty="le--0:#ECC48D;--1:#984E">4Dcli1<1"sp ansty="le--0:#D6DEEB;--1:#403F">53<, sp ansty="le--0:#D9F5DD;--1:#1111">11<()sp ansty="le--0:#D6DEEB;--1:#403F">5<3 sp ansty="le--0:#C792EA;--1:#8844">AE<=>sp ansty="le--0:#D6DEEB;--1:#403F">53sp>< {d ivclassNa="meec-li">53 < sp ansty="le--0:#D6DEEB;--1:#403F">53consoAB0l53(items[i]<);d ivclassNa="meec-li">53< sp ansty="le--0:#D6DEEB;--1:#403F">53}<);d ivclassNa="meec-li">5<3}d ivclassNa="meco"><}d>
44AEco61B0hand443F53< [] ;divclass="Nameec-">44A3F<53 ( spans="tyle--0:#C792EA;--1:#88">44AE344A0<9820 spans="tyle--0:#D6DEEB;--1:#40">3F53<; i spans="tyle--0:#C792EA;--1:#88">4<4AE< spans="tyle--0:#D6DEEB;--1:#40">30<9825 spans="tyle--0:#D6DEEB;--1:#40">3F5<3; i spans="tyle--0:#C792EA;--1:#88">443F5<3) {divclass="Nameec-">3F<53 spans="tyle--0:#D6DEEB;--1:#40">3F53hand4<4AE. spans="tyle--0:#82AAFF;--1:#3B">61B033F53< spans="tyle--0:#D6DEEB;--1:#40">344AEfunc31<111( spans="tyle--0:#D7DBE0;--1:#40">3F53v1<111) spans="tyle--0:#D6DEEB;--1:#40">3F<53 {divclass="Nameec-">dent < spans="tyle--0:#C792EA;--1:#88">44AEre344AEfunc311<11() spans="tyle--0:#D6DEEB;--1:#40">3F<53 {divclass="Nameec-">dent < spans="tyle--0:#C792EA;--1:#88">44AEre3F53 va3F53 < spans="tyle--0:#D6DEEB;--1:#40">3F<53} ;divclass="Nameec-">3F53< spans="tyle--0:#D6DEEB;--1:#40">3F53})<(i) ,divclass="Nameec-">3F<53 spans="tyle--0:#D6DEEB;--1:#40">3F<53) ;divclass="Nameec-">3<);><}di vdivclass="Nameexpressive-">44AEfunc361B0createHan1<111( spans="tyle--0:#D7DBE0;--1:#40">3F536361B0st1<111) spans="tyle--0:#D6DEEB;--1:#40">3F<53 {divclass="Nameec-">de44AEre311<11() spans="tyle--0:#D6DEEB;--1:#40">344 spans="tyle--0:#D6DEEB;--1:#40">3F><53 {divclass="Nameec-">3F53< spans="tyle--0:#D6DEEB;--1:#40">3F53con4<4AE. spans="tyle--0:#82AAFF;--1:#3B">61B<0log spans="tyle--0:#D6DEEB;--1:#40">3F53(it3F<53 spans="tyle--0:#D6DEEB;--1:#40">3F<53} ;divclass="Nameec-">3c44AEco61B0i443F<53 [ spans="tyle--0:#D9F5DD;--1:#11">1<111" spans="tyle--0:#ECC48D;--1:#98">41<111" spans="tyle--0:#D6DEEB;--1:#40">3F<53, spans="tyle--0:#D9F5DD;--1:#11">1<111" spans="tyle--0:#ECC48D;--1:#98">41<111" spans="tyle--0:#D6DEEB;--1:#40">3F<53, spans="tyle--0:#D9F5DD;--1:#11">1<111" spans="tyle--0:#ECC48D;--1:#98">41<111" spans="tyle--0:#D6DEEB;--1:#40">3F<53] ;divclass="Nameec-">44A3F<53 ( spans="tyle--0:#C792EA;--1:#88">44AE344A0<9820 spans="tyle--0:#D6DEEB;--1:#40">3F53<; i spans="tyle--0:#C792EA;--1:#88">4<4AE< spans="tyle--0:#D6DEEB;--1:#40">3F53 i4<4AE. spans="tyle--0:#7FDBCA;--1:#09">6E72le3F5<3; i spans="tyle--0:#C792EA;--1:#88">443F5<3) {divclass="Nameec-">3F<53 spans="tyle--0:#D6DEEB;--1:#40">3F53bu4<4AE. spans="tyle--0:#82AAFF;--1:#3B">61B0addEventList31<111" spans="tyle--0:#ECC48D;--1:#98">4E4Dc1<111" spans="tyle--0:#D6DEEB;--1:#40">3F<53, spans="tyle--0:#82AAFF;--1:#3B">61B0createHan3F53(items[i<])) ;divclass="Nameec-">3<);><}di vdivclass="Nameexpressive-">44AEco61B0hand44A3F53i4<4AE. spans="tyle--0:#82AAFF;--1:#3B">61B<0map spans="tyle--0:#D6DEEB;--1:#40">31<111( spans="tyle--0:#D7DBE0;--1:#40">3F531<111) spans="tyle--0:#C792EA;--1:#88">44AE< => spans="tyle--0:#D9F5DD;--1:#11">11 ><11() spans="tyle--0:#C792EA;--1:#88">44AE <=> {divclass="Nameec-">de3F53con4<4AE. spans="tyle--0:#82AAFF;--1:#3B">61B<0log spans="tyle--0:#D6DEEB;--1:#40">3F53(i4 ><4AE ;divclass="Nameec-">4<4AE} spans="tyle--0:#D6DEEB;--1:#40">3F<53) ;divclass="Name"><})>

This rule is not configurable.

If you are using modern JavaScript with let or const declarations in for loops, each iteration creates a new binding, which can mitigate some of the issues this rule warns about. However, the rule still catches cases where the behavior might be unexpected, so it’s generally beneficial to keep it enabled.

You may wish to disable this rule if you have a specific use case where creating functions in loops is intentional and the captured variable references are the desired behavior.