I'm brand new to JavaScript and currently learning about writing functions shorthand. I just came across this while studying:
const groceries = (groceryItem) => ' - ' + groceryItem;
Is it acceptable/best practice in the real world to write functions like this? (no return, no brackets) I notice that it may be annoying to expand upon. Or is this just standard practice?
I also notice shorthand if statements that have no brackets as well. Also standard practice?
I want to learn good habits early on, so any advice on this matter would be greatly appreciated.
There are several ways to declare functions and there are use cases and pros and cons to each. As a result, there is no "preferred" way. Use the appropriate syntax for your situation.
Below is a summary of the different ways to set up functions with a brief explanation of each. Click on the heading link to be directed to more in-depth resources on that type:
Function Declaration:
function foo(){
}
With a function declaration, the entire function is hoisted (regardless of it's actual location in the code) to the top of the enclosing scope. This makes it possible to invoke the function prior to its declaration point.
Function Expression:
var foo = function(){
}
Function expressions are just variable declarations that assign a function (as data) to the variable. As with function declarations, there is hoisting here too, but only the variable (foo in this example) declaration gets hoisted, not the assignment, so in this case you could not invoke the function prior to its declaration.
Arrow Functions:
const groceries = (groceryItem) => ' - ' + groceryItem;
This is simply a short hand syntax instead of using a function expression. However, there is a difference with an arrow function. With Arrow Functions, the object that this binds to is not affected within the function, while it is affected in a non-arrow function.
Immediately Invoked Function Expression:
(function(){
})();
An Immediately Invoked Function Expression (IIFE) is an anonymous function (a function with no name) that is turned into an expression by wrapping it with parenthesis and then immediately invoked with another set of parenthesis. This syntax is very common in JavaScript and is used to create a scope that doesn't conflict with other scopes.
NOTE:
Functions are the work horses of JavaScript, depending on how you set them up and invoke them, they do many different things:
They can be units of directly invocable code.
They can be the value of a variable or property.
They can be constructor functions that are used to instantiate Object
instances.
They can be raw data that is passed around via arguments.
Yes, I think this is considered acceptable, since arrow functions were specifically designed to allow it. One of the features of arrow functions is that they allow very simple functions to be written as one-liners like this. When you can calculate the return value as a single expression, you don't need to write the body with braces around it or the return statement explicitly. This makes traditional functions needlessly verbose, with more boilerplate than the actual code of the function. The traditional alternative would look like:
const groceries = function(groceryItem) {
return ' - ' + groceryItem;
}
This isn't so bad when defining a named function, but when you're using an anonymous function as a callback, all that verbosity may obscure the intent. Compare:
newarray = oldarray.map(function(x) {
return x * x;
}
with:
newarray = oldarray.map(x => x * x);
Arrow functions are a recent addition to the language, so I think we can assume that the design was given significant consideration. If the Javascript community didn't feel that shorthand functions like this were a good idea, they wouldn't have been allowed in the first place.
The function you wrote is what is commonly known as a "arrow function". They can prove very useful when you get to a somehow more advanced level in JavaScript and there is absolutely nothing wrong with them. On the contrary. Very commonly used with "higher order functions" for arrays, to give an example.
Related
The javascript introduction says:
When I have code like below:
var Person=function(name){
this.name=name;
this.sayHello=function(){return 'Hello '+name;}
}
Whenever I instantiate a "Person", there will be a copy of "sayHello" function in the memory. To reduce this memory consumption, I can change the code like below:
var Person=(function(){
var sayHello=function(){return 'Hello '+name}
return function(name){
this.name=name
this.sayHello=sayHello
}
})()
In this way, there'll not be multiple copies of sayHello()
My questions are:
For the 1st type of code, what's the benefit except wasting more memory?
Should we write code in the 2nd way, or javascript should avoid one copy for one function per instance?
Thanks a lot.
The behavior you are witnessing is the result of two things:
Functions as first-class objects. This means functions are treated the same way as strings, numbers, arrays etc.
How local variables are treated in functions. Local variables are created (typically on the stack) each time the function is called. This allows functions to be called recursively.
This behavior exists in many different languages that have anonymous functions like Go, Perl, Lisp etc.
The two rules above means that each time you call your function the inner function gets created and assigned to the variable.
What's the advantage of this?
The primary advantage of this from the language point of view is consistency of behavior. It means functions are really treated as first-class objects just like numbers, strings etc. Treating it consistently means that people who try to use anonymous functions won't get surprised by the behavior.
How do people use this feature?
Sometimes you find yourself writing several different functions that look similar:
function double (x) {return x * 2};
function quadruple (x) {return x * 4};
Wouldn't it be nice to be able to categorize a "family" of functions that are similar and somehow write them once?
Well, in languages like C you may use a macro system to basically cut-and-paste the text you type to generate several different code.
In languages with first-class-functions you write a function to generate functions:
function makeMultiplier (factor) {
return function (x) { return x * factor }
}
So now you can do:
var double = makeMultiplier(2);
var quadruple = makeMultiplier(4);
Now OBVIOUSLY for this to work the makeMultiplier() function MUST return two different functions. It cannot just modify a single function to do different things each time it is called. Otherwise both the double() and quadruple() functions will multiply by 4 after the second call to makeMultiplier().
Implementation detail
It is possible to create a system whereby the body of inner functions are compiled only once and the differences are captured by a closure. So all functions only occupy RAM once but different versions of a function may occupy more than one closure. It is possible that this is how it's implemented by most js engines but I don't really know. If so, then inner functions do take up additional RAM each time they're defined but not by much (typically by one stack frame - so each function definition takes up the same space as a function call).
From the programmer's point of view though, inner functions must appear to work as if they're created each call because that's how you'd expect them to work.
For the 1st type of code, what's the benefit except wasting more memory?
The only time i'd use something like this is for quick testing of an anonymous object. An example of this would be in some sort of factory implementation:
getWidget = function(){
return {
foo: 'bar',
test: function(){ ... }
}
}
And honestly, this would be quickly replaced with proper coding conventions after I confirmed my initial testing.
Should we write code in the 2nd way, or javascript should avoid one copy for one function per instance?
I'd say no. Don't write code like this. It's unnecessarily convoluted and doesn't appear to work from what I can tell. I'd recommend just creating methods on the function prototype:
var Person = function(name){
this.name = name;
}
Person.prototype.sayHello = function(){
return 'Hello ' + this.name;
}
pros
- easy to read
- easy to manage
- this is scoped properly within the context of calling methods
cons
- a nominal increase in effort to code
- per a comment to the question, you lose access to variables scoped exclusively to the constructor
For the 1st type of code, what's the benefit except wasting more memory?
This could be used for access control (like private in some other languages).
Consider:
var Person=function(name){
this.sayHello = function(){return 'Hello '+name;}
};
name can only be accessed by sayHello, which is a opaque Function.
Other code may replace this.sayHello, but will not be able to let this sayHello instance use another name.
This question already has answers here:
Explain the encapsulated anonymous function syntax
(10 answers)
Closed 7 years ago.
I'm reading up on JavaScript IIFE and so far the understand concept, but I am wondering about the outside parenthesis. Specifically, why are they required? For example,
(function() {var msg='I love JavaScript'; console.log(msg);}());
works great, but
function() {var msg='I love JavaScript'; console.log(msg);}();
generates a syntax error. Why? There are lots of discussions on IIFE, but I'm not seeing a clear explanation about why the parentheses are required.
There are two ways to create functions in JavaScript (well, 3, but let's ignore new Function()). You can either write a function declaration or write a function expression.
A function declaration in itself is a statement and statements by themselves don't return values (let's also ignore how the debugging console or Node.js REPL print return values of statements). A function expression however is a proper expression and expressions in JavaScript returns values that can be immediately used.
Now, you may have seen people saying that the following is a function expression:
var x = function () {};
It may be tempting to conclude that the syntax:
function () {};
is what makes it an expression. But that's wrong. The syntax above is what makes it an anonymous function. And anonymous functions can either be a declaration or an expression. What makes it an expression is this syntax:
var x = ...
That is, everything to the right of an = sign is an expression. Expressions make it easier to write math formulas in programming languages. So in general everywhere that math is expected to be processed is an expression.
Some of the forms of expressions in JavaScript include:
everything to the right of an = operator
things in braces () that are not function call braces
everything to the right of a math operator (+,-,*,/)
all the arguments to the ternary operator .. ? .. : ..
When you write:
function () {}
it is a declaration and does not return a value (the declared function). Therefore trying to call the non-result is an error.
But when you write:
(function () {})
it is an expression and returns a value (the declared function) which may be used immediately (for example, may be called or may be assigned).
Note the rules for what counts as expressions above. From that it follows that braces are not the only things that you can use to construct an IIFE. Below are valid ways for constructing IIFEs (because we write function expressions):
tmp=function(){}()
+function(){}()
-function(){}()
0/function(){}()
0*function(){}()
0?0:function(){}()
(function(){}())
(function(){})()
You may actually see one of the above non-standard forms (particularly the + version) in third-party libraries, because they want to save one byte. But I strongly advise you to only use the brace forms (either are fine), because they are widely recognized as IIFEs by other programmers.
The version of IIFE that is wrapped in parenthesis works, because this marks the declaration of the internal function declaration as an expression.
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
For more detailed explanation please see:
Advanced JavaScript: Why is this function wrapped in parentheses?
HINT:
The invocation operator (()) only works with expressions, not declarations.
This will be a long-winded answer, but will give you the necessary background. In JavaScript there are two ways functions can be defined:
A function definition (the classical kind)
function foo() {
//why do we always use
}
and then the more obscure type, a function expression
var bar = function() {
//foo and bar
};
In essence the same thing is going on at execution. A function object is created, memory is allocated, and an identifier is bound to the function. The difference is in the syntax. The former is itself a statement which declares a new function, the latter is an expression.
The function expression gives us the ability to insert a function any place where a normal expression would be expected. This lends its way to anonymous functions and callbacks. Take for instance
setTimeout(500, function() {
//for examples
});
Here, the anonymous function will execute whenever setTimeout says so. If we want to execute a function expression immediately, however, we need to ensure the syntax is recognizable as an expression, otherwise we have ambiguity as to whether of not we mean a function expression or statement.
var fourteen = function sumOfSquares() {
var value = 0;
for (var i = 0; i < 4; i++)
value += i * i;
return value;
}();
Here sumOfSquares is immediately invoked because it can be recognized as an expression. fourteen becomes 14 and sumOfSquares is garbage-collected. In your example, the grouping operator () coerces its content into an expression, therefore the function is an expression and can be called immediately as such.
One important thing to note about the difference between my first foo and bar example though is hoisting. If you don't know what that it is, a quick Google search or two should tell you, but the quick and dirty definition is that hoisting is JavaScript's behavior to bring declarations (variables and functions) to the top of a scope. These declarations usually only hoist the identifier but not its initialized value, so the entire scope will be able to see the variable/function before it is assigned a value.
With function definitions this is not the case, here the entire declaration is hoisted and will be visible throughout the containing scope.
console.log("lose your " + function() {
fiz(); //will execute fiz
buzz(); //throws TypeError
function fiz() {
console.log("lose your scoping,");
}
var buzz = function() {
console.log("and win forever");
};
return "sanity";
}()); //prints "lose your scoping, lose your sanity"
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does the exclamation mark do before the function?
So I was going back and looking over some of my own code as well as some other javascript code and I realized that a while back when I started writing javascript libraries I was using closures that looked something like this:
(function( window, document, undefined ) {
// code
})( window, document );
But then I saw some bootstrap code and I changed to this syntax:
! function (window, document, undefined) {
// code
}(window, document);
Now, if I'm not wrong (and please correct me if I am), placing the '!' in front of my anonymous function just causes it to be treated as '()' then returns (into nowhere?) a boolean value of whether the value returned by the function was not undefined, null, or empty.
What I'm wondering is, is there really a difference between using the '!()' syntax over '()()'? Are there certain browsers that will complain?
Any thoughts are appreciated, thanks! XD
What you're asking about is self-calling functions, otherwise known as IIFE (immediately invoked function expression). Which is a different thing from a closure. Although it does create a closure (indeed, all functions in javascript create closures, not just IIFE).
It's understandable that you may confuse the two issues though, since IIFE are usually introduced in the context of explaining closures. But be aware that they are different things. Closures are private, shared "global-like" variables. IIFE are functions that gets called immediately upon their definitions.
Now, how does IIFE work? The clue is in the name. It's the "FE" IIFE - function expression.
In javascript, as you know, there are two ways of creating functions - using function declarations:
function foo () {}
and using function expressions:
foo = function () {}
A function expression is simply a function declared in the context* of an expression. What are expressions in javascript? Simply any statement that evaluates something.
Traditionally, people recognize expressions as:
anything on the right side of the = sign
a = /* expression */
anything in braces
(/* expression */)
So traditionally those are the two "standard" ways for declaring function expressions:
foo = function(){}
and
(function(){})
And the second syntax makes it easy to then execute the function object returned by the expression. But, really, an expression is anywhere js does math (or logic, which is math anyway). So adding an operator to a function declaration also turns it into an expression. The following works because they are unary operators (meaning, they are legal without anything on the left hand side):
!function(){}()
+function(){}()
-function(){}() // I especially like this one because it
// looks like a command line switch
typeof function(){}()
But you can also use binary operators if you use some throw-away value or variable with it. The following also work:
x=function(){}()
0==function(){}()
1*function(){}()
2/function(){}()
Heck, you can even abuse the ternary operator:
0?0:function(){}() // valid and works!
There's nothing magical about it. It's not a specific syntax baked into javascript. Just like (function(){}()) is not a specific syntax for IIFE. It's just that when declared in an expression, functions return themselves as objects which can be called immediately.
But I'd advise against using any of the non-standard forms above though. For the same reason you asked this question - most javascript programmers are not used to seeing them and it can cause confusion. I myself didn't realize that you can do this until you asked the question. Still, it's a useful thing to know for when you need to write things like minifiers, code generators etc.
* I'm using "context" in it's traditional definition here not the javascript specific meaning of "context" as defined in the spec.
Nothing, they are just two different ways of achieving the same thing. The () is slightly more readable though.
I often come across Javascript code snippets that consist of many anonymous functions that are called where they are created, such as here:
var prealloc = (function() {
// some definitions here
return function prealloc_win(file, size, perms, sparseOk) {
// function body
};
})();
// can be called like this:
prealloc(...);
So this calls an anonymous function which returns another function prealloc_win. To me this seems equivalent to instantiating a class where the resulting object exposes the function prealloc_win:
function preallocObj() {
// some definitions here
this.prealloc_win = function(file, size, perms, sparseOk) {
// function body
};
}
prealloc = new preallocObj();
// can be called like this:
prealloc.prealloc_win(...);
Is this assumption correct? What are the benefits of using anonymous functions that are called directly? And why is this idiom so often seen in Javascript, but not often in other languages which could be written in the same way (C, C++, Python)?
The deal is that the preallocObj class says that this is something that could be
instantiated multiple times. I could just create more instances of it even though it wasn't really designed for that. You could do some hacks to prevent that but it's easier just to use the immediately invoked anonymous function for this.
With the immediately created and invoked anonymous function, a "class" is created, instantly "instantiated" and assigned to prealloc and
there is no way to reference the original anonymous function that created the prealloc object after this. It was created, invoked and lost.
You pretty much have the right idea. The benefits of this module pattern/function builder are that the resultant function can enclose its own internal definitions or state.
It's basically just a way to create a function with private variables or constants. Consider the less efficient alternative:
var prealloc = function() {
// some definitions here
// function body
}
Every time this function is called it would reassign/instantiate its variables, adding unnecessary performance overhead and overwriting any state data that resulted from previous calls.
This method is useful when there are some variables that are important to the workings of a function that you want only private access to or that you need to persist between invocations without contaminating the outer scope.
Javascript is fundamentally very different to C++, JAVA and Python and should be written in differnt ways. At the risk of repetition, Javascript is not an OOP language it is a prototype language. Douglas Crockford (inventor of JSON) at Yahoo has some wonderful articles and particuarily Videos entitled 'Javascript - the good parts' you should watch them all.
This question already has answers here:
Explain the encapsulated anonymous function syntax
(10 answers)
Closed 8 years ago.
In the YUI library examples, you can find many uses of this construct:
(function() {
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event,
layout = null,
...
})();
I think the last couple of parentheses are to execute the function just after the declaration.
... But what about the previous set of parentheses surrounding the function declaration?
I think it is a matter of scope; that's to hide inside variables to outside functions and possibly global objects. Is it? More generally, what are the mechanics of those parentheses?
It is a self-executing anonymous function. The first set of parentheses contain the expressions to be executed, and the second set of parentheses executes those expressions.
It is a useful construct when trying to hide variables from the parent namespace. All the code within the function is contained in the private scope of the function, meaning it can't be accessed at all from outside the function, making it truly private.
See:
http://en.wikipedia.org/wiki/Closure_%28computer_science%29
http://peter.michaux.ca/articles/javascript-namespacing
Andy Hume pretty much gave the answer, I just want to add a few more details.
With this construct you are creating an anonymous function with its own evaluation environment or closure, and then you immediately evaluate it. The nice thing about this is that you can access the variables declared before the anonymous function, and you can use local variables inside this function without accidentally overwriting an existing variable.
The use of the var keyword is very important, because in JavaScript every variable is global by default, but with the keyword you create a new, lexically scoped variable, that is, it is visible by the code between the two braces. In your example, you are essentially creating short aliases to the objects in the YUI library, but it has more powerful uses.
I don't want to leave you without a code example, so I'll put here a simple example to illustrate a closure:
var add_gen = function(n) {
return function(x) {
return n + x;
};
};
var add2 = add_gen(2);
add2(3); // result is 5
What is going on here? In the function add_gen you are creating an another function which will simply add the number n to its argument. The trick is that in the variables defined in the function parameter list act as lexically scoped variables, like the ones defined with var.
The returned function is defined between the braces of the add_gen function so it will have access to the value of n even after add_gen function has finished executing, that is why you will get 5 when executing the last line of the example.
With the help of function parameters being lexically scoped, you can work around the "problems" arising from using loop variables in anonymous functions. Take a simple example:
for(var i=0; i<5; i++) {
setTimeout(function(){alert(i)}, 10);
}
The "expected" result could be the numbers from zero to four, but you get four instances of fives instead. This happens because the anonymous function in setTimeout and the for loop are using the very same i variable, so by the time the functions get evaluated, i will be 5.
You can get the naively expected result by using the technique in your question and the fact, that function parameters are lexically scoped. (I've used this approach in an other answer)
for(var i=0; i<5; i++) {
setTimeout(
(function(j) {
return function(){alert(j)};
})(i), 10);
}
With the immediate evaluation of the outer function you are creating a completely independent variable named j in each iteration, and the current value of i will be copied in to this variable, so you will get the result what was naively expected from the first try.
I suggest you to try to understand the excellent tutorial at http://ejohn.org/apps/learn/ to understand closures better, that is where I learnt very-very much.
...but what about the previous round parenteses surrounding all the function declaration?
Specifically, it makes JavaScript interpret the 'function() {...}' construct as an inline anonymous function expression. If you omitted the brackets:
function() {
alert('hello');
}();
You'd get a syntax error, because the JS parser would see the 'function' keyword and assume you're starting a function statement of the form:
function doSomething() {
}
...and you can't have a function statement without a function name.
function expressions and function statements are two different constructs which are handled in very different ways. Unfortunately the syntax is almost identical, so it's not just confusing to the programmer, even the parser has difficulty telling which you mean!
Juts to follow up on what Andy Hume and others have said:
The '()' surrounding the anonymous function is the 'grouping operator' as defined in section 11.1.6 of the ECMA spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf.
Taken verbatim from the docs:
11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:
Return the result of evaluating Expression. This may be of type Reference.
In this context the function is treated as an expression.
A few considerations on the subject:
The parenthesis:
The browser (engine/parser) associates the keyword function with
[optional name]([optional parameters]){...code...}
So in an expression like function(){}() the last parenthesis makes no sense.
Now think at
name=function(){} ; name() !?
Yes, the first pair of parenthesis force the anonymous function to turn into a variable (stored expression) and the second launches evaluation/execution, so ( function(){} )() makes sense.
The utility: ?
For executing some code on load and isolate the used variables from the rest of the page especially when name conflicts are possible;
Replace eval("string") with
(new Function("string"))()
Wrap long code for " =?: " operator like:
result = exp_to_test ? (function(){... long_code ...})() : (function(){...})();
The first parentheses are for, if you will, order of operations. The 'result' of the set of parentheses surrounding the function definition is the function itself which, indeed, the second set of parentheses executes.
As to why it's useful, I'm not enough of a JavaScript wizard to have any idea. :P
See this question. The first set of parenthesis aren't necessary if you use a function name, but a nameless function requires this construct and the parenthesis serve for coders to realize that they've viewing a self-invoking function when browsing the code (see one blogger's best-practices recommendation).