What's more important in JS: performance, or the understandability of the code?

That is only necessary when the word fuction is at the start of the line - so as to ensure it is treated as a function expression rather than trying to parse it as a function statement and therefore giving an error when it can’t find the name.

The () on the end is what makes it an IIFE so there’s no need to look at the start to determine if it is an IIFE or not.

Of course you can wrap any JavaScript code inside of ( and ) if you think it makes it more readable.

Another point is that some people simply add ! in front of the word function when creating an IIFE that is not assigned to anything rather than wrapping it in ( and ). This has the same effect of having something in front of the word function so that it can be identified as a function expression with one fewer characters to type but with it trying to perform a NOT operation on the undefined value returned (which of course still gives undefined) - this variant will not work if the value returned is to be assigned to something as we have here.

Oh dear god, I just got the shudders from the mere thought of using that technique. It’s likely to be commonly used in code golf competitions though, for it keeps the number of used characters down to an absolute minimum, along with in general how well the code can be understood :slight_smile:

You two have beaten this horse to death :smile:

function addEvent() {}
var addEvent = function() {}

There are no gotcha’s with the second variation, they behave the same way as every other variable so that’s the only type of function you need to know about. If you prefer the first, that’s fine but it is less flexible(can’t reassign) and can lead to errors(hoisting) so I think it’s best avoided entirely.

Personally, I use a linter to catch hoisting mistakes.

I don’t understand why everyone in this thread has been saying that. Function declarations are absolutely reassignable.

function f() {
    console.log('f');
}
f = function() {
    console.log('f2');
}
f(); // f2

That being said, for the sake of our code being understandable, we shouldn’t reassign functions, regardless if it’s a function expression or declaration.

What if someone tries to call removeEvent before addEvent?

Well until the first event has been added there is nothing to remove so having it do nothing is perfectly correct.

Why not use var and avoid them entirely?

Yeah, you’re right. I find it less clear what’s happening though as the vars are created for you dynamically.

One way to do things is better than many if it works everywhere and there are no downsides.

If you ‘use strict’ then vars are not created for you and anything that hasn’t been defined gives a syntax error.

One of the downsides that I’ve found is that by exclusively using function expressions, you lose the ability of the code to express to you its intention.

I don’t know about for others, but for me a common coding convention is where function declarations imply that they are fully encapsulated, doing something with their input and returning a result, and importantly, not messing with anything else outside of the function.

Whereas function expressions are used to indicate that something additional will be done, whether that be to make use of other variables from the function scope or to fiddle with other variables outside.

It’s a small benefit of the different coding styles of declarations and expressions, but one that will be sad to lose.

You should never be doing those things except where the function is actually a method and is sharing access to the properties of the object. Then you have a choice between defining the function inside the object constructor where it will be unique to that object or adding the function to the object’s prototype so it can be shared between objects.

Remember that ALL functions in JavaScript are both methods and objects even though one of the ways of defining them hides that and makes it more difficult to work out which object the function is a method of.

[quote=“felgall, post:29, topic:223000, full:true”]
You should never be doing those things except where the function is actually a method and is sharing access to the properties of the object.[/quote]

Yes indeed, however even your addEvent function reaches out and mucks around with both the addEvent and removeEvent variables. I question such techniques, for normally there are better ways to do these things.

Yes, this particular situation is one of the few where there isn’t a better way. Of course once we decide to drop support for IE8 this particular browser patch becomes unnecessary.

Anyway, the only alternative to this particular one is somewhat messier and a lot less obvious as to what it is doing and why it works::

<script type="text/javascript">
/*@cc_on
  @if (@_jscript)

function addEvent(ob, type, fn ) {
          var eProp = type + fn;
          if ('string' === typeof ob) ob = document.getElementById(ob);
          ob['e'+eProp] = fn;
          ob[eProp] = function(){ob['e'+eProp]( window.event );};
          ob.attachEvent( 'on'+type, ob[eProp]);
       };

  @end
@*/
</script>
<script type="application/javascript">
function addEvent(ob, type, fn ) {
         if ('string' === typeof ob) ob = document.getElementById(ob);
         ob.addEventListener(type, fn, false );
      };v
</script>

[quote=“felgall, post:31, topic:223000, full:true”]
Yes, this particular situation is one of the few where there isn’t a better way.[/quote]

Why are IIFE’s not a better way? Let’s compare the two:

Functions that reach out and change external variables.

var removeEvent;
var addEvent = function (...) {
    // using lazy evaluation
    ...
    addEvent = function (...) {
        ...
    };
    removeEvent = function (...) {
        ...
    };
    addEvent(...);
};

Compared with using IIFE’s to return the appropriate function:

var addEvent = (function () {
    // invoked immediately
    ...
    return function (...) {
        ...
    };
}());
var removeEvent = (function () {
    // invoked immediately
    ...
    return function (...) {
        ...
    };
}());

Are there reasons why IIFE’s are not a better technique to use for this type of situation?

Sorry, I don’t see it - you’re talking about this right?

var myFunction = function() {}

vs

function myFunction() {};

I find them equally clear, but the second has more voodoo magic.

How do you mean? I can’t see that here:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
"use strict";

console.log(addEvent);
function addEvent() { }

</script>
</body>
</html>

The voodoo magic is an aspect that we choose to avoid these days, where function declarations are hoisted along with declared variable names.

Separate from that, I find that the difference of notation helps to convey different information about them. Both notations would work equally well, but using separate notations helps to provide a visual clue as to how I intend for the function to behave.

My intention for a function declaration is that it does nothing more than return a result based on its input, not changing anything else outside of it.

function sum(a, b) {
    return a + b;
}

Nice and simple.

With a function expression, my intention is to convey the message to the person reading the code, that it’s going to do something with the local scope, or to reach out and change something.

For example:

var increaseCounter = function () {
    counter += 1;
};

It’s not a hard and fast rule, and both types of function declarations or expressions work equally as well a each other. It’s just a handy convention that I’ve found helpful that makes the code more expressive about its intentions.

[quote=“markbrown4, post:34, topic:223000, full:true”]
How do you mean? I can’t see that here:[/quote]

You can spot the difference with the following code:

console.log(addEvent1);
console.log(addEvent2);
function addEvent1() {}
var addEvent2 = function() {};

We shouldn’t code this way of course. Common convention is that functions should be declared before you use them, which is wise.

While using the var statement helps to ensure that, I personally find that the two different forms of notation can be used to convey subtle information to the coder about function’s intention.

It’s similar to using parentheses around an IIFE to help convey information to the coder that something more than just a normal function is going on here, even if the enclosing parenthesis are strictly not required in this particular situation.

var someFunc = (function () {
    ...
}());
var anotherFunc = function () {
    ...
}

When the coder sees the someFunc line, he can be immediately warned by the enclosing parenthesis that what follows is not a normal function expression, but will instead be invoked at the end.

If an IIFE is written without the enclosing parenthesis, it can be too easy to miss the difference.

var someFunc = function () {
    ...
}();
var anotherFunc = function () {
    ...
}

The lines with the var statements are too similar to each other. Enclosing the top IIFE helps to more easily inform the coder about what is happening.

You seem mistaken about this:

var sum = function(a, b) {
    return a + b;
}

Nice and simple?

I can’t see what Felgall was referring to with strict mode, no.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
"use strict";

console.log(addEvent1);
console.log(addEvent2);
function addEvent1() {}
var addEvent2 = function() {};

</script>
</body>
</html>

Gives the same output as this, no errors thrown.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">

console.log(addEvent1);
console.log(addEvent2);
function addEvent1() {}
var addEvent2 = function() {};

</script>
</body>
</html>

Ahh yes that matter. It will be nice to gain some clarification on.

Normally the main benefit of strict mode is to warn you when a variable assignment will result in a global variable instead.

I’m not sure what you’re getting at here.

As I mentioned in that post, using either function declarations or function expressions both result in the same behaviour from the function. The intention instead is to convey different information about the function being fully encapsulated or not.