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

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

Then we’re equally confused with each other :smile:

You started going on about pure functions when that has no relation to how they’re declared, at all.

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

An IIFE is a function expression - just like the ones you are complaining about.

See https://developer.mozilla.org/en/docs/web/JavaScript/Reference/Operators/function for a further explanation of function expressions such as IIFEs.

I think this threads usefulness may have been exhausted long ago, I vote for a lock :slight_smile:

1 Like

[quote=“felgall, post:42, topic:223000, full:true”]
An IIFE is a function expression - just like the ones you are complaining about.[/quote]

Please note that I am not complaining about function expressions. I have no problem with people using them at all.
What I have been saying is that I personally find that the different syntax of function declarations and function expressions has been beneficial to give an indication as to their intent.

This may also be a cry of “but what of the buggy whip makers!” on my part, for I’ve found substantial benefit from using both declarations and expressions to make my code more expressive. Having said that though, I fully recognise and understand that some coding conventions of today nail things down more tightly with the enforcement of only function expressions. Function declarations are on the way out, like the buggy-whip makers of old.

So no, I am not complaining about using function expressions. It has been the sole use of them at the expense of everything else that I have been attempting to delve in to instead.

Having got that off our chest, what do you think are the pros and cons between using a function expression to reach out and change local variables, versus using IIFE’s to return the desired type of function?

An example function expression reaching out to change things:

var removeEvent;
var addEvent = function (...) {
    ...
    if (...) {
        removeEvent = function (...) {};
    else if (...) {
        removeEvent = function (...) {};
    }
    ...
};

And an example IIFE to assign the appropriate function:

var removeEvent = (function () {
    if (...) {
        return function (...) {
            ...
        };
    } else if (...) {
        return function (...) {
            ...
        };
    }
}());

But we have the pros and cons of function expressions versus IIFE’s to work through :smile:

IIFEs are function expressions so what is it we need to compare between function expressions that happen to be self executing and those that are not self executing?

Wow, thank you for the education.

[quote=“felgall, post:46, topic:223000, full:true”]so what is it we need to compare between function expressions that happen to be self executing and those that are not self executing?
[/quote]

What we are comparing here is the appropriateness of function expressions reaching out to change variables external to the function, and IIFE’s to instead assign functions to those variables.

The addEvent and removeEvent functions seem to be a good example to work with here, as they have come up in recent discussions.

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.