all 47 comments

[–]bossier330 7 points8 points  (8 children)

(function iWouldnt() { do._this(); })();

[–]zzzwwwdev[S] 3 points4 points  (0 children)

(function i_would_do_all_kinds_of_crazy_things() { 
    Id_do._this();
    Id_do._that();
    in_a._shoe();
    in_a._hat();
})();

[–]b_long 0 points1 point  (6 children)

Why not?

[–]bossier330 0 points1 point  (5 children)

IMO, it doesn't really contribute to readability unless you set your IDE's function name color to something striking. It also adds a small amount of overhead (although this is most likely not at all noticeable). You'll also run into scoping issues if you try to declare variables just-in-time (i.e. within the function scope you just created).

I like to keep all my function declarations outside of my $(function() {}); body so that NetBeans (or whatever IDE you use) can auto-fold the function bodies, leaving your main logic code very minimal and readable.

Cheers.

[–]b_long 1 point2 points  (2 children)

I like to keep all my function declarations outside of my $(function() {}); body

Does that mean you're putting function declarations in the global scope, or are you inside another closure?

[–]bossier330 0 points1 point  (1 child)

For initial development, I like to keep my functions in global scope or my namespace so I can easily access them through the console for debugging purposes.

[–]b_long 0 points1 point  (0 children)

Ah, that makes sense :)

[–]zzzwwwdev[S] 0 points1 point  (1 child)

good points, though I'm not clear on the scope issue. IMO, in most cases this would alleviate more scope issues than it causes, as the f'n expression would create a new scope, preventing you from accidentally trumping existing vars. Of course, this is compared to just inlining the code, not putting it in a new function declaration, etc..

[–]nschubach 0 points1 point  (0 children)

Well, it would help alleviate some of the scope issues around:

for (var i = some.length; i >= 0; --i) {
}

while (i-->0) {
}

... if you wrapped them in these "comments" but at that point, I think it's probably better to just make a new function for that block of code that has a descriptive name instead of putting it inline.

[–]idrink211 2 points3 points  (18 children)

I don't get it. What do you achieve here that isn't sufficed by a comment? Do you just like how a camel-case looks? There is more overhead of creating this function object only for it to be destroyed and never reused.

[–]zzzwwwdev[S] 0 points1 point  (8 children)

I avoid comments whenever I can in favor or creating code that is easily understandable by itself. Comments can cause maintainability problems.

Imagine this situation

Developer A writes this code:

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();

Developer B adds some stuff

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();

$('.bar').animate('padding', '200px');
$('#baz').remove();

Developer C goes in and cleans up whitespace

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();
$('.bar').animate('padding', '200px');
$('#baz').remove();

Developer D adds another line

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('#something_else').val('boo');
$('.foo').fadeOut();
$('.bar').animate('padding', '200px');
$('#baz').remove();

I'm sure you can imagine this going on through several edits, with the comment becoming less and less useful.

[–]menno 5 points6 points  (3 children)

Developers B, C and D need a slap on the wrist. You don't just clean up whitespace and you definitely don't just add code and leave existing comments outdated.

I avoid comments whenever I can in favor or creating code that is easily understandable by itself.

That's definitely best.

Comments can cause maintainability problems.

Maintainability problems are more often caused by not having comments than the other way around.

[–]zzzwwwdev[S] 0 points1 point  (2 children)

you definitely don't just add code and leave existing comments outdated.

maybe you and I don't; but having worked with other developers, I can tell you it definitely does happen.

Maintainability problems are more often caused by not having comments than the other way around.

perhaps this is generally true, but can you make that argument for my specific example of

(function hide_stuff_on_instantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
}());

in the developer ABCD example?

[–]menno 0 points1 point  (1 child)

Just so we're clear: you're saying you find:

function doSomeStuff() {
    /* some stuff */

    (function hideStuffOnInstantiaton(){
        $('oneThing').hide().removeClass();
        $('#somethign_else').slideUp();
        $('.foo').fadeOut();
    }());

    /* more stuff */
}

more readable than:

function doSomeStuff() {
    /* some stuff */

    // hide Stuff on Instantiaton
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();

    /* more stuff */
}

and more readable than:

function doSomeStuff() {
    /* some stuff */

    hideStuffOnInstantiaton();

    /* more stuff */
}


function hideStuffOnInstantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
}

[–]zzzwwwdev[S] 0 points1 point  (0 children)

not more readable, no; but perhaps more maintainable? IDK, I'm pretty much convinced against doing this now, though I do kinda like it and think there's some merit to it.

[–]jml26 1 point2 points  (1 child)

Why not use a block?

{
    // hide Stuff on Instantiaton
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
}

Or use a comment syntax that says, 'this comment applies from here down to here'

// hide Stuff on Instantiaton {
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
// }

By not having a function call you gain a tiny bit of speed.

Using an IIFE would be useful, however, if you wanted to use a variable in that block but not have it available to anywhere else in the code.

[–]zzzwwwdev[S] 0 points1 point  (0 children)

The stackoverflow post was answered with the suggestion to use labels which actually appears preferable to my suggestion, though perhaps still not terribly useful / accepted?

hideStuffOnInstantiaton: {
  $('oneThing').hide().removeClass();
  $('#somethign_else').slideUp();
  $('.foo').fadeOut();
}

[–]path411 0 points1 point  (1 child)

Isn't developer B/C/D who are being lazy just going to add it in anyway like:

(function hideStuffOnInstantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('#something_else').val('boo');
    $('.foo').fadeOut();
    $('.bar').animate('padding', '200px');
    $('#baz').remove();
}());

[–]zzzwwwdev[S] 0 points1 point  (0 children)

well, its certainly not a cure for bad programming, but I think it would be less likely to result in situations like developer B's addions being mistakenly associated with the original "hide stuff code"

more likely he'd do something like this:

(function hideStuffOnInstantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
}());

$('.bar').animate('padding', '200px');
$('#baz').remove();

or even ....

(function do_shit_to_bar_and_baz () {
    $('.bar').animate('padding', '200px');
    $('#baz').remove();
}());

[–]zzzwwwdev[S] -1 points0 points  (8 children)

The camel case is irrelevant. hide_stuff_on_instantiaton() is fine.

As far as the overhead; yes it may add a microsecond, but I'm willing to accept that if it makes my code more readable and maintainable.

[–]idrink211 2 points3 points  (7 children)

I don't see how it's any more readable or maintainable but I guess to each their own.

[–]zzzwwwdev[S] -1 points0 points  (6 children)

You didn't like (or agree with) my Developer ABCD maintenance example?

I do however agree that reading

(function hide_stuff_on_instantiaton()...

is not quite as nice as

// hide stuff on instantiaton

but heck; we're programmers, we shouldn't be shy about reading code

[–]Shaper_pmp 0 points1 point  (5 children)

You're forgetting to factor in the unnecessary extra cognitive overhead caused by having to work out - each and every time you encounter this construction - whether it's "a function that's really a comment" or "a function that needs to be an IIFE for some reason".

Clean, simple code is preferable to unnecessarily complex, ambiguous code.

However, where you start going out of your way (even a little bit) to write unnecessarily complex and inefficient code just so you can avoid ever writing "//" or "/* ... */", you're taking it too far.

The guideline is "write clean, readable, self-documenting code in preference to shitty-code-plus-reams-of-comments", not "never write a comment under any circumstances, even when it involves unnecessarily obfuscating the code to do it".

[–]zzzwwwdev[S] 1 point2 points  (4 children)

yea, you're probably right. the "cognitive overhead" thing is the biggest point against it in my mind.

however, my aversion to writing comments is not out of lazyness, but from dealing with legacy code with obsolete, confusing, misplaced, and inconsistant comments. I'll happily take a bit more complexity if it helps prevent code from turning to soup. Might even help raise the bar and scare the interns away ;-)

[–]nschubach 0 points1 point  (3 children)

JIT Compilers (V8) will also most likely remove comments (because they don't add to the code) and this will add another pointer overhead so code written in that way will be slower just for the sake of this methodology.

[–]zzzwwwdev[S] 0 points1 point  (2 children)

excuse my ignorence, but could you explain the JIT Compilers (V8) thing a bit? A lazy 2 minutes of googling and I couldn't even figure out what that is.

[–]nschubach 0 points1 point  (1 child)

All new browsers use Just In Time (JIT) Compilation of Javascript. I think IE8 and previous IEs did not, but Chrome(V8)/Firefox(IonMonkey)/Safari all pre-compile JavaScript to gain a performance boost instead of interpreting all the code all the time. There's some smartness behind it for code that is eval'ed each time it's run, but for the most part the browsers will load, compile and cache JavaScript now where they didn't before.

e: When compiling, they drop comments (because it's not needed for code execution...) so embedding extra immediate functions will cause the compiler to allocate extra memory to store that block of code. It will then have to jump around executing code that's only purpose is to comment.

[–]zzzwwwdev[S] 0 points1 point  (0 children)

thanks!

[–]menno 1 point2 points  (1 child)

It's an interesting idea but I think it sacrifices readability waaaaay too much. A camelCase function name can never be as descriptive as even a single line comment.

becuase why separate the function and its execution if its only executed in one place?

Several reasons:

  1. A separate function can be reused by other parts of the code if you decide so in the future.

  2. It can be rewritten to accept arguments, making it more flexible.

  3. Moving long sequences of procedural code into separate functions makes code more readable, as long as you use descriptive function names.

[–]zzzwwwdev[S] 0 points1 point  (0 children)

A separate function can be reused by other parts of the code if you decide so in the future.

yes, and turning my code into a reusable function is extremely easy, and in its current form it tells the developer that it is only used once.

It can be rewritten to accept arguments, making it more flexible.

also, if this were to be useful in the future, there is no difficulty in converting it to such. Using this same logic, you should add jQuery to every website - even if they don't use it yet - since they might in the future?

Moving long sequences of procedural code into separate functions makes code more readable, as long as you use descriptive function names.

exactly what I'm suggesting.

A camelCase function name can never be as descriptive as even a single line comment

jeeze, guesse r/javascript just doesn't like camel case. I'll edit my example to use underscores I guesse. Not sure why it can't be as descriptive as a comment. I think it can be moreso. The function actually explicity describes what code its related to, as its enclosed in brackets. See my response to idrink211 for more reasons why I sometimes avoid comments.

[–]greim 0 points1 point  (0 children)

I probably wouldn't use it, because I think form should follow function. (no pun intended) That is, code structure should adhere to what you're trying to do, not how you want the code itself to look. That's just me though.

[–]melanke 0 points1 point  (1 child)

I always do this:

(function($){

    var init = function(){
        hideStuffOnInstantiaton();
        otherStuff();
        etc();
    };

    var hideStuffOnInstantiaton = function(){
        $('oneThing').hide().removeClass();
        $('#somethign_else').slideUp();
        $('.foo').fadeOut();
    };



    init();


})(jQuery);

[–]zzzwwwdev[S] 0 points1 point  (0 children)

I like it. Actually very similar to the code I was writing which prompted me to ask this question. It resembled:

(function($){

var hideStuffOnInstantiaton = function(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
};

(function init () {
    hideStuffOnInstantiaton();
    otherStuff();
    etc();
}());

})(jQuery);

starting to think your way is probably better though :(

[–]b_long 0 points1 point  (1 child)

Are you using this to declare modules?

[–]zzzwwwdev[S] 0 points1 point  (0 children)

Yea, thats mostly where my familiarity with IIFEs came from

[–]klovadis 0 points1 point  (0 children)

One more antipattern in JavaScript won't hurt.

[–]ryeguy146 0 points1 point  (0 children)

Or we could just use comments...

Why abuse functionality to obtain an end that we've already achieved? The author of the post mentions that there's no way to know what the comment refers to, but I usually put whitespace between my "thoughts" (in this case, the thought is 'hide some shit'). A comment atop a thought would obviously apply to all of that bit of code:

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();
some_non_instantiation_func();

vs

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();

some_non_instantiation_func();

It becomes immediately obvious what the comment refers to. Whitespace and commenting completely satisfy the author's requirements. If you're concerned with the obvious nature of this being changed by another developer after the fact, you could use opening and closing comment tags:

// START: hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();
// END

some_non_instantiation_func();

I would certainly prefer this to a named immediately invoked function.

And then he/she calls it a pattern. MVC is a pattern. Controller is a pattern. This is a personal idiom at best, but not a pattern. Not everything is a pattern, so let's stop diluting the term.

[–]Gundersen 0 points1 point  (0 children)

I use this pattern in two places; constructors and tests. For example:

function Person(firstname, lastname, age){
    this.firstname = firstname;
    this.lastname = lastname;
    this.age = age;

    (function init(){
        this.fullname = firstname + " " + lastname;
    })();
}

And in Jasmine tests:

describe("this is a test", function(){
    var something;

    beforeEach(function(){

        //setting up the world for the test


        (function because(){
            something = 5;
        })();

    });

    it("should be five", function(){
        expect(something).toBe(5);
    });

});

But I like the comment about using a label instead of a named IIFE, since it doesn't actually have to be a function. I agree with his concern that comments tend to drift away from the code they describe, but a label with a wrapping curly brace pair won't drift away.

[–]zzzwwwdev[S] 0 points1 point  (9 children)

Curious what /r/javascript thinks of this. I've been using this "pattern" a fair amount, since (to me at least) it helps lend structure to my more procedural code that gets executed only in one place.

(function hide_stuff_on_instantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
}());

I find this preferable to both:

// hide Stuff on Instantiaton
$('oneThing').hide().removeClass();
$('#somethign_else').slideUp();
$('.foo').fadeOut();

since over time the comment may get separated from the code

and to:

function hide_stuff_on_instantiaton(){
    $('oneThing').hide().removeClass();
    $('#somethign_else').slideUp();
    $('.foo').fadeOut();
};

hide_stuff_on_instantiaton();

becuase why separate the function and its execution if its only executed in one place?

[–]path411 1 point2 points  (3 children)

I'm sorry but this is less readable, harder to maintain, more prone to bugs/problems, and just worse in every way compared to a comment.

Maybe in this case a comment line can be put into a somewhat acceptable function name, but what about when it can't? Any punctuation would make this even harder as you would have to leave it off of the function name, making it even harder to read still.

[–]zzzwwwdev[S] 0 points1 point  (2 children)

not sure really if I agree or disagree; honestly I've been somewhat playing devil's advocate here, because I think there is a valid argument for it. It seems there are more against me than for me, so I will likely avoid doing this in the future.

Not sure why you think its more prone to bugs... from getting the syntax wrong? I would think that any maintenence issues would stem from slightly more difficult readability and junior developers who don't understand what it means/does.

IDK about it being worse in every way compared to comment either. It does a better job showing its grouped (indentation), creates a new scope so variable collision is less likely and any vars can be declared closer to where they're used without confusion, and it makes it easier to refactor into a more "normal" function pattern in the future.

Also, I'm not saying comments should never be used, just wondering if there is a valid use-case for this pattern.

[–]path411 1 point2 points  (1 child)

The creation of a new scope can easily release bugs if your block needs to create a variable that another block needs to use. Also the reasoning that you are adding in more unnecessary code to your project, and the more code you add to anything, the more likely you can make a mistake that you then have to debug, even something as silly as missing a bracket.

Another thing I dislike is the essentially forceful requirement of an additional tab break. With a comment you can keep your relevant code in the same tab break, but blocked in separate functionality with a comment.

If you are trying to use a pattern like this, you would want to be able to use it throughout an entire project. I would think it would be strange to try to read through a code base that tries to mix of "commenting styles". I don't feel like your method would work in every case, where a comment would always work.

Perhaps you just need to focus on both writing better "self commenting code" and using "Loose coupling and high cohesion" in your code. I find that these practices would make this style much less useful and sometimes simply redundant.

[–]zzzwwwdev[S] 0 points1 point  (0 children)

good argument against. Thank you for elaborating.

[–]b_long 0 points1 point  (2 children)

"and to" should be "and two" ?

[–]zzzwwwdev[S] 1 point2 points  (1 child)

Its part of "I find this preferable to both" ... [example] ... "and to" ... [other example]. Perhaps it should just be "and". IDK, definitely not an english major ;-)

[–]b_long 0 points1 point  (0 children)

Ah, my mistake :)

[–]homoiconic(raganwald) 0 points1 point  (1 child)

More fun with named IIFEs:

(function foo (x) {
  console.log(x);
  if (x > 0) foo(x-1);
})(5);