Coffeescript parentheses for function invocation - javascript

Coffeescript gives the freedom to set or omit parentheses for functions calls. Like
alert 'Hi folks'
alert ('Hi folks')
are equal.
Now I am wondering, probably due to insufficient experience with coffeescript, its syntax and its aim to keep things simple, if it possible to add parentheses for a statement like the following. I know they aren't necessary.
define (require) ->
return 'goodbye'
Edit: If I apply the option to set parentheses in the same manner as for the alert statement, than I would assume this syntax shouldn't make any difference to the final js.
define ((require) ->
return 'goodbye'
)

define (require) ->
return 'goodbye'
would be equivalent to the JavaScript code
define(function(require) { return 'goodbye' })
That is, a function call to define with a function as its first (and only) argument. It is probably not what you expected the snippet to do when you asked your question.
Something I found very helpful when I played around with CoffeeScript was to try things out in the on-line "try CoffeeScript" dialogue on the CoffeeScript website. This allows you to see the JavaScript that a given snippet is compiled to, and immediately see what effect e.g. adding parentheses or changing indentation has on the resulting JavaScript code. I definitely recommend doing that. :-)
Edit to reflect the edit in the question:
Yes, adding parentheses around the function ((require) -> return 'goodbye') is valid, and doesn't alter the behaviour. Note however that "foo (bar)" and "foo(bar)" is parsed differently by the parser; in the former the parenthes denote precedence (priority, "regular parentheses"), and in the latter they are function invocation parentheses.
"foo bar", "foo(bar)", "foo (bar)" all do the same thing, but whereas "foo bar, baz" and "foo(bar, baz)" work fine, "foo (bar, baz)" is a syntax error.

Yes, you can wrap an anonymous function in parentheses.
I ran this simple script.
test.coffee
define = (func) -> func()
console.log define ((require) ->
return 'goodbye'
)
output:
goodbye

Related

What does the colon mean in this JavaScript snippet (not an object literal)?

I apologize for posting a duplicate-looking question, (I know, that there is a bunch of similar titled questions here), but none of the questions already present seems to suit my case.
In short, what does the colon do here:
<script>
'use strict';
foo: 1;
//whatever else
</script>
I supposed this to be a syntax error, but it's not. And it's not a label, I think, since adding a line break foo; throws Uncaught SyntaxError: Undefined label 'foo' (though a doc page suggests exactly this, that it's a label).
I suppose this is some recent addition to the JavaScript syntax, since I have never heard of such use of the colon.
If anyone wonders, why I'm asking this, this is my explanation: I was reading an MDN doc page and there is an example:
var func = () => { foo: 1 };
// Calling func() returns undefined!
It shows, that the curly braces in this case are treated as block delimiters and not an object literal. So I supposed, that somehow foo: 1 on its own must be syntactically legal. And indeed it is.
There is a question, which is supposed to cover every use of the colon in JavaScript, but it doesn't mention this, and no answer there does this either.
If you'd have read further down the page you linked, you would see why it was written like that.
var func = () => { foo: 1 };
This is an attempt to return an object from a arrow function.
That doesn't work for reasons explained here:
This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal). (source)
So the returned value needs to be wrapped in parentheses:
var func = () => ({foo: 1});
To actually answer your question:
It's a label.
You can't just take the foo: 1 out of context like that.

Error : missing new prefix when invoking a constructor

I am trying to create a function in node.js. The following is relevant code, it gives me error when i call function.
function ReplacePlaceholders() {
return 'success';
}
exports.sendMailMsg = function (templateName, receiverEmail, dataPlaceholders) {
ReplacePlaceholders();
}
In node.js, function names are camel cased, and should start with a lowercase character. Starting a function with an uppercase character tells JSHint to consider the function a constructor rather than a method.
This is actually an error being generated by JSHint, but the code will run correctly. The option in JSHint, newcap, which causes this error is actually depreciated, and disabling it is recommended.
The relevant info as to why this option is even in JSHint:
This option requires you to capitalize names of constructor functions. Capitalizing functions that are intended to be used with new operator is just a convention that helps programmers to visually distinguish constructor functions from other types of functions to help spot mistakes when using this.
Not doing so won't break your code in any browsers or environments but it will be a bit harder to figure out—by reading the code—if the function was supposed to be used with or without new. And this is important because when the function that was intended to be used with new is used without it, this will point to the global object instead of a new object.
The error message you mention is a JSHint error message, not a runtime error. There is a discussion of it here:
jshint expects the new 'prefix' for functions
JSHint expects functions that start with a capital letter to be object definitions. You can ignore the error, disable it in JSHint, or rename your function so that it starts with a lower-case letter.
I'm not sure why that might be, but that error suggests that doing new ReplacePlaceholders(); might work. Though, you may want to consider something like the following:
function ReplacePlaceholders(templateName, receiverEmail, dataPlaceholders) {
return 'success';
}
exports.sendMailMsg = ReplacePlaceholders;

Why does 'onhashchange'in(window) work?

'onhashchange'in(window)
Having in() work is not a surprise, as new(XMLHTTPRequest) or typeof(x) are other examples of this construct, but not having to separate the string and in is.
Is this per ECMAScript specs? It works in Chrome and FF, haven't tested IE.
From what I can tell, there's no difference whether you wrap window in parenthesis or not in this particular instance. Either way, it checks for this member on the window object.
Might be less confusing if you use spaces:
'onhashchange' in (window)
The same as
'onhashchange' in window
in is not a function, but when you remove the spaces I can see how you read it as such. One advantage to wrapping window in parenthesis is that you can then minify the code:
'onhashchange'in(window)
Something you could not do without the parenthesis.
' is a token that ends a string, so a pair of '' are semantically unambiguous, you don't need whitespace after the end of a string for the lexer to know that it has reached the end of a string.
Another way of saying that is that this works for the same reason that 'Hello '+'world' works.
Additionally, in is a keyword, not a function. It seems like you're thinking of () as the "function call operator", but in this case it's just a disambiguating parentheses.
It's like asking "why does 1 +(2) work?" + doesn't become a function just because you follow it with a paren, and similarly the following will work:
function foo(){}
foo
();
Javascript is brittle with its whitespace rules.
I'm not sure if the notation is confusing you (that maybe in() is a method?), but in is one of those elements of JS that few people correctly understand (I didn't really understand it until quite recently). This is a simplified version showing what in does:
var foo = {
'bar':1,
'barbar':2
}
console.log('bar' in foo); //true
console.log('baz' in foo); //false
What makes this all the more confusing is that you can use in inside a for() loop, as if it (in) were an iterator. The way I tend to think of for loops is like this:
for (exp1; condition; exp2) {
/* statements */
}
for (condition) {
/* statements */
}
In other words, the loop will continue until the in condition fails, which will happen when it runs out of members.

How to register Jquery click event with coffeescript on rails 3.1

I am trying to do what seems like it should be simple, but for some reason is eluding me. I want to add a click event to a link in my tasks.js file like so:
$ ->
$('.cancel_task').click ->
$('#task_form').toggle
This renders out as:
(function() {
$(function() {
return $('.cancel_task').click(function() {
return $('#task_form').toggle;
});
});
}).call(this);
All I want is something like:
$('.cancel_task').click(function()
{
$('#task_form').toggle();
});
How do i accomplish this with coffescript and the rails 3.1 stack?
Coffee is supposed to wrap everything you do in a limited scope so you don't populate the world with globals. This is useful, unless you have, don't ignore this. At the top level, you can export with a this.something = "value".
Now your code above doesn't work because function calls need a paren when there are no parameters. This will make the two snip-its functionally the same. Functions are variables in JavaScript, so it just assumes you want to return that function instead of it's result without the parens.
$ ->
$('.cancel_task').click ->
$('#task_form').toggle()
Lastly, a Coffee function always returns the last value of the function. It's just how it works. So don't worry about the return statements, you can always ignore the results.
The second snippet you posted is the correct output from coffee, and the second and last snippets you posted are (in practical terms) functionally equivalent. If you want you can get rid of the top-level closure by using coffee's --bare option (this is documented) but otherwise you should not fret about CoffeeScript's output unless it's causing you problems.

Why use (function(){})() or !function(){}()?

I was reading In JavaScript, what is the advantage of !function(){}() over (function () {})()? then it hit me, why use :
(function(){})() or !function(){}() instead of just function(){}()?
Is there any specific reason?
It depends on where you write this. function(){}() by itself will generate a syntax error as it is evaluated as function declaration and those need names.
By using parenthesis or the not operator, you enforce it to be interpreted as function expression, which don't need names.
In case where it would be treated as expression anyway, you can omit the parenthesis or the operator.
I guess you are asking why use:
var fn = (function(){}());
versus:
var fn = function(){}();
The simple answer for me is that often the function on the RHS is long and it's not until I get to the bottom and see the closing () that I realise I've been reading a function expression and not a function assignment.
A full explanation is in Peter Michaux's An Important Pair of Parens.
A slight variation on RobG's answer.
Many scripts encompass the entire program in one function to ensure proper scoping. This function is then immediately run using the double parentheses at the end. However, this is slightly different then programs which define a function that can be used in the page but not run initially.
The only difference between these two scenarios is the last two characters (the addition of the double parentheses). Since these could be very long programs, the initial parenthesis is there to indicate that "this will be run immediately."
Is it necessary for the program to run? No. Is it helpful for someone looking at the code and trying to understand it? Yes.

Categories

Resources