-
Notifications
You must be signed in to change notification settings - Fork 9.4k
declare var to fix scope error #15265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
By not declaring var i = 0, the code is referencing the i declared in the outer function. This causes an infinite loop condition that crashes browsers as multiple methods modify the value of i.
Just adding some more context for anyone searching for this issue ... When adding a new marketing rule (or maybe any action that creates the catalog tree checkbox view (the category chooser) in the admin), the browser (tested on FF & Chrome) will hang on catalogs with child categories where buildCategoryTree and processCategoryTree are called infinitely as both will ultimately modify the |
@keithbentrup: your extra description reminded me of this very recent ticket: #15121 Nice work btw! |
@hostep Yep, that issues describes the scenario perfectly. Added to the fixed issues. |
Lifesaver @keithbentrup ! |
@@ -168,7 +168,7 @@ define([ | |||
} | |||
|
|||
if (parent && config && config.length) { | |||
for (i = 0; i < config.length; i++) { | |||
for (var i = 0; i < config.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kieronthomas, thank you for collaboration.
According to Magento Code Style guideline we should declare a variables in the top of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@VladimirZaets nothing to do with me, I think you meant to refer to @keithbentrup ^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok @VladimirZaets so update it accordingly if you need to. It's a P1 ticket that's crashing browsers. Fix it and move on.
Incidentally, that rule may be part of the reason why the error exists in the first place ... with this perhaps ill-advised rule, declaring vars far removed from their use.
For your consideration,
- https://stackoverflow.com/questions/5053073/is-defining-every-variable-at-the-top-always-the-best-approach
- https://medium.com/@bluepnume/theres-no-need-to-define-all-javascript-vars-once-at-the-top-of-a-function-and-there-hasn-t-been-a66b31f21822
Also linking to the whole style guide without linking to the specific rule isn't particularly helpful. You're asking contributors to follow rules that you can't even find/link to.
I couldn't even find the rule googling and limiting the domain to just site:devdocs.magento.com. The most relevant section that I could find with a bit of searching which has no mention of declaring it at the top: https://devdocs.magento.com/guides/v2.3/coding-standards/code-standard-javascript.html#variable-declarations. You have to go parse the eslint configuration json to actually find the rule you're bringing up.
Lastly, I doubt you're going to fix all the other unrelated errors picked up by the linter for this file, so arbitrarily fixing it for these and not others seems capricious.
Anyway, I'm more concerned with this being resolved. You now know the cause of the error and the solution. You don't need anything further from me to bring it to a resolution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@keithbentrup if there is such rule we cannot violate it. Changing existing conventions is out of scope for PR processing.
@VladimirZaets we can probably move var
declaration to a proper place on our side as an additional commit.
@keithbentrup thank you for contributing. Please accept Community Contributors team invitation here to gain extended permissions for this repository. |
These are loop variables and they should be set with |
@DanielRuf In JS loops are haven't the self scope. The |
@orlangur yes, I will fix it. |
Oh well, this makes it harder to keep track of them as loops like in the changeset should use their own local variable instances instead of using a variable which is available in the context of the whole function. Also then you have to rename one of them and create unique variable names. Personally I find this Code Styles rule for loops wrong and is not best practice in the frontend / JS world. |
@DanielRuf For it, we add the rule for ESLint to do this process more transparently. You can read more about the hosting and variable scopes in JS. |
I see it differently. Loops should always have the var declaration in the condition / head.
Not what is in the head of the loop and not if you use let. I guess you mean hoisting and I know what this is ;-)
No, a block is a context. A block is also a loop (anything with a curly brace in most cases). In general |
I would propose to use |
Also see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for for best practice (var used in head of loop). |
@DanielRuf For the Mozilla example, it does not really matter if other projects have other rules, Magento coding style can always be reasonably changed (hope so, never saw in action :)), but it should be some separate effort, not in scope of an arbitrary PR. |
@DanielRuf We haven't any transpalier like I don't sure that examples https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for is the best practice rather than the simple overview of From the book JavaScript: The Good Parts Douglas Crockford:
|
That's not right anymore with
https://devdocs.magento.com/guides/v2.0/install-gde/system-requirements_browsers.html Officially IE11+ so you can still use |
@VladimirZaets are you referring to a partial support in IE11 https://caniuse.com/#feat=let ? I'm not sure if it can cause any troubles, but maybe there are some browsers not mentioned in this table but requiring support. |
Normally not as we use let and const in projects. Well, then let's create unique var names. The reuse of such a iterator variable / pointer and defining this on top of the function / block scope does not feeld good generally and can introduce other issues. |
See also line 188 for similar issue. |
Try this:
|
"Same" issue. There are just these 2 changes here. Interesting, still old Varien code =) I guess it should be ok to set the vars at the top of these (very little) methods but it feels wrong for me as frontend dev working with Node.js and JavaScript on a daily basis. ;-) |
Sorry Dan, came to this pull from #15121. And was pointing out the issue with scope in the next function as well. |
Hi @keithbentrup. Thank you for your contribution. Please, consider porting this solution across release lines. |
By not declaring
var i = 0
, the code is referencing the i declared in the outer function. This causes an infinite loop condition that crashes browsers since multiple methods modify i from the other scope.Description
Fixed Issues (if relevant)