I found this snippet in this minified JS by Google:
_ga.utils.getValidColumnGroups = function(a) {
for (var b = [], c = 0, d; d = _ga.metadata.items[c]; ++c)
d = d.attributes.group,
a && (d = _ga.utils.getNormalizedName(d)),
-1 == b.indexOf(d) && b.push(d);
return b
};
Without focusing too much specifically on what this function is doing,
I wonder how this loops will end when the conditions statement is assigning values and not the typical comparison operator?
d = _ga.metadata.items[c]What will happen especially with variable
din this line?var b = [], c = 0, d;In normal cases, it will assign with the last statement of the comma. But maybe it is not the cases in certain situation. If not, the first two assignment is useless. What these lines do?
d = d.attributes.group, a && (d = _ga.utils.getNormalizedName(d)), -1 == b.indexOf(d) && b.push(d);
-
2if d end up with a boolean or undefined value (or any variant that a condition read as false), the loop will end. And for the second part, this is just instanciation, to be sure that we are working wih the correct scope variable.AxelH– AxelH2016年05月23日 06:55:21 +00:00Commented May 23, 2016 at 6:55
-
@AxelH: That makes sense! Feel free to make it as the answergeckob– geckob2016年05月23日 06:57:48 +00:00Commented May 23, 2016 at 6:57
-
@AxelH—using a variable declaration with var in a for expression only limits scope to the surrounding execution context. let is required to limit scope to the for block. ;-)RobG– RobG2016年05月23日 07:03:16 +00:00Commented May 23, 2016 at 7:03
-
Just did, a bit more verbose ;)AxelH– AxelH2016年05月23日 07:03:22 +00:00Commented May 23, 2016 at 7:03
-
1@AxelH—yes, it comes as a bit of a surprise for those coming from other languages. :-) Dunno about "secure", it's never been a big issue. New declarations const and let are more about cross–compiling from other languages that filling gaps in the language.RobG– RobG2016年05月23日 07:15:37 +00:00Commented May 23, 2016 at 7:15
3 Answers 3
I wonder how this loops will end when the conditions statement is assigning values and not the typical comparison operator?
d = _ga.metadata.items[c]
The result of that expression is the value assigned to d, so the loop will end if d is assigned a falsey value (i.e. if _ga.metadata.items[c] returns a falsey value like undefined, 0, null, etc.).
What will happen especially with variable d in this line?
var b = [], c = 0, d;
That is simply some chained variable declarations. It declares b, c and d and initialises them with an empty array, the number zero and undefined (the default when variables are declared) respectively.
Comments
As in most languages, the for loop is described as follows:
for(a; b; c) d;
- Run instruction
a - Run instruction
band convert the result to boolean. - If the boolean was true, run instructions
dandcand evaluate instructionbagain, else end the loop.
Since in JavaScript collections return undefined when you try to access beyond their length, and undefined converts to the boolean false, you can iterate through an array-like object like this:
for(var i=0, item; item = myArray[i]; ++i) {
// code here
}
Since you're probably going to use the item anyway, it's a good idea to store it in a variable to make the code more efficient and clean. It's even more useful with objects that aren't exactly arrays, such as a NodeList, because their length property actually takes some time to compute (this can vary between browsers). The Google JavaScript Style Guide actually recommends doing this for that reason.
-1 == b.indexOf(d) && b.push(d);
This is a very, very ugly code practice. It abuses the && operator to do this:
if(b.indexOf(d) == -1) b.push(d);
It saves 1 character and makes the code a lot less readable. Never do that.
1 Comment
I wonder how this loops will end when the conditions statement is assigning values and not the typical comparison operator?
d = _ga.metadata.items[c]
The condition can be write without any operator, like a simple infinite loop
while(true){}
this can be write like
var infinite = true;
while(infinite){}
but also
var infinite;
while(infinite = true){} //this is a frequente mistake witch and up with infinite loop instead of while( infinite== true);
Basicly, you first set the value then check the condition.
In you example, this work for every other variant that a condition read as false like an undefined
What will happen especially with variable d in this line?
var b = [], c = 0, d;
This is the declaration part of the loop. You are allowed to declare as many as you want in the first part of a for(;;) loop.