Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript function fails to return object when there is a line-break between the return statement and the object?

Tags:

javascript

Here is the jsfiddle

The full code:

function foo1(){     return {msg: "hello1"}; } function foo2(){     return     {msg: "hello2"}; }  // output = "foo1 =  {"msg":"hello1"}" console.log('foo1 = ' , JSON.stringify(foo1()));   //output = " foo2 =  undefined " console.log('foo2 = ' , JSON.stringify(foo2())); 

The difference between the two is that in foo2, the {msg: 'hello'} is in its own new line. I was expecting the parser to ignore whitespaces?

like image 321
dchhetri Avatar asked Aug 14 '13 01:08

dchhetri


People also ask

Can a function return an object JavaScript?

To return an object from a JavaScript function, use the return statement, with this keyword.

What happens when JavaScript function reaches a return statement?

When a return statement is used in a function body, the execution of the function is stopped. If specified, a given value is returned to the function caller. For example, the following function returns the square of its argument, x , where x is a number. If the value is omitted, undefined is returned instead.

Do line breaks matter in JavaScript?

JavaScript ignores spaces, tabs, and newlines that appear in JavaScript programs. You can use spaces, tabs, and newlines freely in your program and you are free to format and indent your programs in a neat and consistent way that makes the code easy to read and understand.

What does === return in JavaScript?

What is === in JavaScript? === (Triple equals) is a strict equality comparison operator in JavaScript, which returns false for the values which are not of a similar type. This operator performs type casting for equality. If we compare 2 with “2” using ===, then it will return a false value.


2 Answers

tl;dr The line break is causing the 'undefined' in the second function. JavaScript doesn't require semicolons in a lot of cases and just assumes them in certain contexts (Automatic Semicolon Insertion).


In certain cases, to avoid this ASI problem and for aesthetic reasons, I use the so-called grouping operator. For example, with the hoquet templating DSL (it compiles Arrays as s-expressions into HTML), I like to group the Arrays so that they clearly show the HTML structure:

return (   ["ul"   , ["li"     , ["span", {class: "name"}, this.name]     , ["span", {id: "x"}, "x"]     ]   ] ); 

which seems somewhat clearer, or more consistent to me than

return [   "ul",   [     "li",     ["span", {class: "name"}, this.name],     ["span", {id: "x"}, "x"]   ] ]; 

and they end up with the same number of lines. But it's a matter of aesthetics, really.


The grouping operator just evaluates whatever expression is inside of it. You see this commonly with Immediately Invoked Function Expressions, where you need to turn what would normally be a function declaration into an expression, which can then be immediately invoked (hence, the name). However, a perhaps lesser known feature of the grouping operator is that it can also take a comma-delimited list of expressions, e.g.

function() {   return (     doSideEffects(),     console.log("this is the second side effect"),     1 + 1   ); } 

In this case it evaluates each of these expressions and returns only the last one (1 + 1).

like image 151
tjb1982 Avatar answered Sep 30 '22 03:09

tjb1982


Accepted Answer seems to be correct.

However I found this variant of a return line with line break at a function arg opening bracket DOES work:

myFunction(){   return myOtherFucntion(            myArg); } 

And this other variant with line break before '.' dot operator ALSO works:

myFunction(){   return myObject            .myObjectFunction(); } 

(The style/readability of my examples are obviously a bit odd, but try to just pay attention to the conclusions they make, and exercise your own style as you find appropriate).

like image 26
cellepo Avatar answered Sep 30 '22 02:09

cellepo