Dangerous Implications of Allman Style in JavaScript

Dangerous implications of Allman style in JavaScript

return cannot have LineTerminator after it so:

return
{

};

is treated as return; (return undefined) instead of return {}; (return an object)

See the rules for Automatic Semicolon Insertion (ASI) for more.

Is block style really this important?

The silent error is that undefined is returned!

Semicolons are optional in JavaScript, and therefore

return
{
ok: false
};

is parsed as if it were

return;  // Leaves function straight away
{
ok: false
};

JSLint will recognize such patterns and warn about them:

lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement

lint warning: missing semicolon

lint warning: unreachable code

lint warning: meaningless block; curly braces have no impact

This has been discussed on SO in the "Strangest language feature" question.

Are there semicolon insertion dangers with continuing operators on next line?

If you take some syntactically valid line and punctuate it with line breaks, automatic semicolon insertion will not apply (except in the narrow case of return, throw and very few other statements, listed below). ASI only occurs when there is absolutely no other way to interpret the code. Certainly, there is a way to interpret your multiline code as a single statement, because it is valid as a single line. In short, ASI is generally a tool of last resort in the parser's attempt to understand the program.

To cite ES5, the first case of ASI detailed in the spec occurs...

  1. 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...

But that case is naturally eliminated, because you had a grammatically valid line before you injected a newline into it. Thus, this case of ASI cannot apply to your case because it depends upon a span of code that is not syntactically valid without semicolons. You don't have that here.

(The other two cases don't apply either; the second case applies to the end of a program and the third case applies to continue, break, return, throw, and postfix ++/-- operators.)

The common problem people have with ASI occurs when an author has two lines which he expects will stand separately, but those two lines happen to cause no grammatical problem when understood as a single line. That case starts with two lines and they accidentally become one. Your cases is the inverse: you start with one line; it does not accidentally become two.

JSLint - Expected to see a statement but instead saw a block

It's a much easier a problem than squiggly bracket placement. You have a particular type of block -- an empty block -- and JSLint doesn't like empty blocks. It wants statements.

Note that a function without a return value returns undefined anyway, so you can kludge this without changing function like this:

/*jslint sloppy:true, white:true */
/*global Sessions, $http, baseURL */
Sessions.getVars = function()
{
return $http.get(baseURL)
.then(function(response) { return response.data; },
function(response) { return undefined; });
};

I think that's all you're seeing.

Note that JSLint is not necessarily quite as bad about where you put the squigglies as these other answers would have you believe! ;^) It's not a dealbreaker, anyhow, if you use JSLint directives.

I'm using two directives:

  • sloppy -- allows you to skip using "use strict";
  • white -- allows for any whitespace you want. Without this, you'd see the error I think other answers here are anticipating, but that error would be Expected exactly one space between ')' and '{'.

I'd say you can just run the snippet on JSLint.com to check, but it looks like Crockford is in the middle of his warned move to a new JSLint that's much more draconian than the old one. For now, I'd suggest testing snippets at old.jslint.com.

If you do, you'll see that, to make JSLint "fully happy", you'll need to remove response from that second function as well: function() { return "Something"; });. It doesn't like unused parameters either.

If you want to keep the TODO comment, you'll need to add the todo directive too.

Adding both of those changes gives us:

/*jslint sloppy:true, white:true, todo:true */
/*global Sessions, $http, baseURL */
Sessions.getVars = function()
{
return $http.get(baseURL)
.then(function(response) { return response.data; },
function() {
/* TODO Error handling; add `err` to parameters */
return undefined;
});
};

Javascript scope -- var vs global

The problem is that every time one of these is clicked, you're adding a new submit event handler to your form. But the first one will always fire first. When you don't declare the var, you're overwriting the variable that that first handler is looking at. But the mistake is adding a new handler every time. I would do it like so:

var currentUnknownBox;
jQuery('#letter_input_form').submit(function()
{
var letter = jQuery("#letter_input").val();
jQuery("#letter-input-dialog").dialog('close');
jQuery("#letter_input").val('');
that.validateAndSaveLetter(currentUnknownBox, letter);
//Do not let the form actually submit
return false;
});
jQuery("#letter-input-dialog").dialog({autoOpen: false});

jQuery(".box.unknown").live('click',function(){
currentUnknownBox = this;

//if we are NOT on mobile, use jQuery UI dialog
if (!Drupal.settings.is_mobile)
{
jQuery("#letter-input-dialog").dialog('open');
} else {
var letter = prompt('Please enter a letter to use in your guess');
that.validateAndSaveLetter(currentUnknownBox, letter);
}
});

Incidentally, .live is deprecated. You should use .on instead.

Exports' naming convention - how does it work?

I think you are refering to "dll name mangling"

name mangling

It's used to make sure exports names are unique

You can specify a .def file which will make it easier to use afterwards

Simply put, a .def file is just a text file containing the following structure

LIBRARY "MyDll"

EXPORTS
exportFunction1

Call child method from parent class Javascript

Is it a good practice to call child method from a parent class?

Yes, this is totally normal. However, your base class should either provide a default implementation for constructHtml, or declare it as abstract (in TypeScript). To be precise, it is only a good practice to call methods declared on the class itself, although they might be (or even expected to be) overridden in a subclass.

the call to this.constructHtml() returns undefined

That's because you have a return; statement doesn't return anything. Remove the linebreak. Don't use Allman brace style in JavaScript.



Related Topics



Leave a reply



Submit