97

Possible Duplicate:
Javascript syntax: what comma means?

What does this pattern return? How does it work?

return myfunc(), myobj.myvar = someobj.prop, myobj

I have not come across this pattern before but have been looking at the Bing Maps Ajax Control and have noticed this pattern several times.

As I understand it multiple values are not returned. So what does this pattern do? What is returned? What is this pattern's benefit?

Community
  • 1
  • 1
Duncan Gravill
  • 4,082
  • 6
  • 31
  • 48
  • Does it return a set of arguments; like how you can overload the parameters in a function call? – Luke Merrett Apr 23 '12 at 16:35
  • 2
    "What is this patterns benefit?" — It doesn't have one. It is confusing, non-idiomatic code. – Quentin Apr 23 '12 at 16:37
  • I cannot see any reason... It even places more objects on the stack than if there was three normal instructions... – Denys Séguret Apr 23 '12 at 16:41
  • 1
    This question and its answers were very valuable to me, i.e. this question should not be marked as a duplicate. The so-called "original" question addresses the general usage of commas, but this question here is more specific. I came here looking for insight into the transpiled code emitted from the Typescript Playground when using a decorator, and this question and its answers helped me immensely. My google searches probably would not have lead me to the "original" question, and even if it did I would have been unsatisfied. So, thank you to the asker and responders. – Andrew Willems Jun 14 '16 at 14:03

3 Answers3

168

It's the comma operator. It evaluates its left-hand operand, throws the result away, evalutes its right-hand operand, and takes that as its result value. It's left-to-right associative, so a, b, c evaluates a, then b, then c, and takes the result of c as its value.

In your example, it's exactly like:

myfunc();
myobj.myvar = someobj.prop;
return myobj;

Some people really prefer to do things on one line, even when there's no objective reason to. There no benefit in the example you gave, and in fact it's confusing because it makes it look like the first two bits relate to the value that will ultimately be returned, which they don't. (I wrote that before you told us it was minified code; obviously, being unclear to humans is only an issue in source code, not minified code.)

Since you've said it's a minifier: The very small possible benefit the minifier might have gotten there is if this is part of a conditional block: It can save one or two characters. If we assume the long form looked like this:

if (someCondition) {
    myfunc();
    myobj.myvar = someobj.prop;
    return myobj;
}

...using the comma operator, the minifier can do this (63 characters):

if(someCondition)return myfunc(),myobj.myvar=someobj.prop,myobj

...rather than this (65 characters):

if(someCondition){myfunc();myobj.myvar=someobj.prop;return myobj}

...without changing the functionality of the code, if what follows is a } or some other appropriate character (or end-of-file) to trigger automatic semicolon insertion at the end. Otherwise, it would need the ; on the first one, but that still saves one character.

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • 29
    +1 (I've just learned a new thing) – MilkyWayJoe Apr 23 '12 at 16:41
  • 5
    What's worse is that you can put all that on one line. Using a `,` instead of a `;` just allows the `return` statement to go at the front where it will confuse maintainers. – Quentin Apr 23 '12 at 16:41
  • This is actually what I suspected but it just seemed strange that the first two statements don't appear before the return statement if they aren't going to be returned. The code is minified, I wonder if it has something to do optimization and minification? I don't really see how it would make any difference. – Duncan Gravill Apr 23 '12 at 16:47
  • @FunkyFresh84 not with optimization, but with minification purposes, minify any code using any minificator and you will see a lot of these comma operators – ajax333221 Apr 23 '12 at 16:50
  • @FunkyFresh84: You will see minifiers do fun things with the comma operator. I wouldn't have expected to see this particular example, but the comma operator is definitely one of the tools in the minification toolkit. In this case, there's just no gain, though. As Quentin pointed out, `myfunc();myobj.myvar=someobj.prop;return myobj;` is just as short. But it's probably a side-effect of using the comma operator in other situations where there *is* some slight benefit. – T.J. Crowder Apr 23 '12 at 16:52
  • Thanks everyone for your expertise and experience! I was umming and arring whether to just test it out or ask a question. But actually I think I have learnt extra from the question, and it's hopefully helpful for others too! – Duncan Gravill Apr 23 '12 at 17:01
  • @Crowder thanks, it seems a bit extreme but I guess the bytes add up. – Duncan Gravill Apr 23 '12 at 17:23
  • 5
    @FunkyFresh84: A minifier wouldn't be doing its job if it didn't save a character wherever it can safely do so. ;-) –  Apr 23 '12 at 17:24
  • @T.J.Crowder Maybe I'm missing something here, but it seems to me the first one is 63 characters (not 64) a net saving of 2 characters (not 1). As you trade semi-colons for commas, but you drop both curly braces. So even with semi-colon added at end it'd still save 1 character? – user17753 Jan 30 '13 at 19:09
  • @user17753: Thanks! I can't believe A) I counted wrong, and B) None of the other dozens of people who read this answer pointed that out. :-) Fixed. – T.J. Crowder Jan 30 '13 at 21:34
  • It is one of those dumb legacy JavaScript things. Nobody really needs it these days, but it is kept for compatibility reasons. – vitaly-t Apr 23 '19 at 21:58
  • 2
    @vitaly-t - The comma operator? No, definitely not just legacy. In fact, it's getting more use now than it did five years ago, thanks to concise arrow functions, where people shoehorn in a side-effect: `a = map(v => (v.method(), v.prop));`. (I'm not a fan of that, but people do it.) – T.J. Crowder Apr 24 '19 at 06:09
12

The comma operator evaluates (from left to right) the expressions and then it returns the last result, which in this case will be the evaluation of the myobj identifier.

You can do this eliminate some curly braces if that's important to you...

if (true)
    ;// do something
else
    return myfunc(), myobj.myvar = someobj.prop, myobj

...as opposed to...

if (true)
    ;// do something
else {
    myfunc();
    myobj.myvar = someobj.prop;
    return  myobj;
}
1

in your example myobj should be returned where as every thing before gets executed

myfunc();
myobj.myvar = someobj.prop;
return myobj;
Tobias Krogh
  • 3,340
  • 17
  • 14