views:

104

answers:

4
  • What are the dangers of breaking a line of long code up at a close parenthesis?

  • When could a semicolon be automatically inserted by Javascript (presumably that is the danger, right?).

  • Why is using a ) as a line breaker "frowned upon" by JSLint?

In Javascript I sometimes see one long line of code broken up at a ) like this (example):

function ()
{

or like this (example):

object.methodOne()
      .methodTwo();

But when reading the line break expectations for jsLint, it says:

As a further defense against the semicolon insertion mechanism, JSLint expects long statements to be broken only after one of these punctuation characters or operators:

, ; : { } ( [ = < > ? ! + - * / % ~ ^ | &
== != <= >= += -= *= /= %= ^= |= &= << >> || &&
=== !== <<= >>= >>> >>>=

JSLint does not expect to see a long statement broken after an identifier, a string, a number, closer, or a suffix operator:

. ) ] ++ --

So the close parenthesis is singled out as a line breaker that JSLint "doesn't expect to see."

I would prefer to use

function() 
{

since I find it more readable, and I already use it in other languages, but currently I use:

function () {

Could I safely use the ) to break up long lines?

+2  A: 

When you're trying to return an object,

return {
 'foo': 'bar'
}

will return the object, whereas

return
{
  'foo': 'bar'
}

will return undefined. Javascript will automatically insert a semicolon after return in the second example, and the object will never be reached.

For functions, because function() isn't valid on its own, it shouldn't make a difference if the brace is on the same line or the next.

See also section 7.9.1 Rules of Automatic Semicolon Insertion of the ECMAScript specification. Aside from return, there are four other situations where a semicolon will be inserted due to a newline: break, continue, throw and ++ or --.

When a continue, break, return, or throw token is encountered and a LineTerminator is encountered before the next token, a semicolon is automatically inserted after the continue, break, return, or throw token.

Daniel Vandersluis
So you're saying that a line break after `function ()` or `object.method()` could never insert a semi colon before the next continuing row?
Peter Ajtai
For `function()`, JS shouldn't insert a semicolon. For `object.method()`, I don't believe it'll insert a semicolon if there is a newline before further chained method calls (from testing and experience), but I'm not 100% on what the spec is in this situation (because `object.method()` is valid syntax).
Daniel Vandersluis
Thanks. In practice I've never had a problem with those sort of line breaks, but I'm always paranoid that there's some browser out there that won't interpret my code correctly because of it, or that there's some corner case I'll run into...
Peter Ajtai
+2  A: 

This link should explain it all:

JavaScript Semicolon Insertion

The "danger" is with (taken from the above link, emphasis added):

There are five restricted productions in the grammar, they are the postfix operators ++ and --, continue statements, break statements, return statements, and throw statements.

function() is not in that "danger" list. However, when writing semi-colon free-code (I'm not sure if this is your aim :-), one should guard against lines starting with characters -- such as ( or [ -- that may start or continue an expression. The following code shows an example of code which is likely wrong:

x()
(function (){...})()

As you can see, using ) as a line-breaker may make the expression able to continue on subtly without an explicit semi-colon iff the next line can continue the expression. I write the proceeding as (if the following is indeed the intent):

x()
;(function (){...})()

Personally, I dislike JSLint :-) Happy coding.

pst
A: 

It is safe.

I took a quick look at the semicolon insertion rules in the spec (3rd edition), and for function declarations it is OK.

Šime Vidas
Take a look at section 7.9.1. There are five situations where inserting a new line will cause a semicolon to be inserted where it is not desired.
Daniel Vandersluis
I was referring to function declarations. function x() LINE_BREAK { is OK. Also true for function expressions.
Šime Vidas
+3  A: 

A semicolon will be inserted only if the following line is not a valid continuation of the previous line (see exceptions below). So function() { with { on the next line is always safe.

From the ECMAScript spec:

When, as the program is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true:

• The offending token is separated from the previous token by at least one LineTerminator.

• The offending token is }.

Exceptions to this rule are the increment/decrement operators, continue, break, return and throw, whose arguments must always be on the same line:

When a ++ or -- token is encountered where the parser would treat it as a postfix operator, and at least one LineTerminator occurred between the preceding token and the ++ or -- token, then a semicolon is automatically inserted before the ++ or -- token.

When a continue, break, return, or throw token is encountered and a LineTerminator is encountered before the next token, a semicolon is automatically inserted after the continue, break, return, or throw token.

casablanca