
Preparing Yourself for Modern JavaScript Development - Tenhundfeld
http://www.codethinked.com/preparing-yourself-for-modern-javascript-development
======
wickedchicken
I always find it odd that the same developers who deride PHP look at things
like IIFE and think "wow, JS is a cool, modern language!"

Thanks for the article though, if I ever need to write some JS this will help
keep me a little more sane.

~~~
azakai
> I always find it odd that the same developers who deride PHP look at things
> like IIFE and think "wow, JS is a cool, modern language!"

I don't deride PHP (I don't know it), but I see nothing wrong with IIFE. Yes,
it could benefit from some syntactic sugar, but otherwise it is just using one
of the best features of JavaScript, function support (first-class functions,
anonymous functions, etc.).

It makes perfect sense to use a pattern like IIFE in order to encapsulate
code, often using closures to allow access in a controlled manner from the
outside, etc.

I suppose perhaps you don't like closures and so forth, and that's fine, but
many people including me love them.

~~~
ufo
IIFEs are cumbersome and non-intuitive. Better languages have block scope or a
"let" statement instead.

~~~
TazeTSchnitzel
`let` is drafted for ECMAScript 6.

~~~
georgemcbay
...and ECMAScript 4 had block scope.

Language design by committee is seriously flawed and until a feature is
shipping in all the major browsers it isn't real.

~~~
TazeTSchnitzel
ECMAScript 4 was cancelled.

~~~
georgemcbay
That was exactly my point.

------
ender7
This is a nice, gentle introduction, but if you're going to start using
modules you might as well go slightly farther and use something like RequireJS
(<http://requirejs.org/>) or Browserify (<https://github.com/substack/node-
browserify>).

~~~
combataircraft
both RequireJS and Browserify are not good options. Browserify's
implementation is awkward, incomplete and pollutes global scopa a lot.

Check out OneJS: <http://github.com/azer/onejs>

It's the only tool that lets you structure your client-side project as a
CommonJS package and produces unobtrusive code mixable with anything in same
global scope.

~~~
kvnn
There is another comment on this thread, by a separate user that reads:

"both RequireJS and Browserify are not even good options. Browserify's
implementation is awkward, incomplete and pollutes global scope a lot. Check
out OneJS"

I think there may be an agenda behind these comments.

~~~
combataircraft
I'm the owner of both comments and wrote it for two times because I can't see
the other one and have very strong opinions about this topic.

~~~
saurik
(That other account has apparently been hell-banned, seemingly due to a
downvotes during a political conversation about Kim Jong-il that you were
involved in; you should probably stop using that account, as users can only
see your posts if they turn on showdead. FWIW, thank you very much for this
comment about OneJS, despite the flak you got for it due to the post from your
hell-banned account.)

------
pgambling
Here are a couple book recommendations for those of you looking to improve
your JavaScript:

"JavaScript: The Good Parts" by Douglas Crockford "JavaScript Patterns" by
Stoyan Stefanov

~~~
stuff4ben
The Crockford book is 4 years old now, is it still considered to be a good
book to pickup? I've done JS off and on for a while, but mostly haphazardly
(with an emphasis on the hazard). I'm looking to start doing some backbone.js
and jquery and a book to help start off with it.

~~~
phillmv
Despite being a small book you can ignore a good third of it, and I think his
constructor pattern is out of date? but - it does do a good job of explaining
the actually idiosyncratic thing about js - the whole prototype chain thing,
and the scoping.

~~~
pgambling
Even though I recommended the book, I completely agree with you.

------
Xcelerate
That was a well-written article that has a pattern that should work well for a
lot of people. But I think it can be improved.

One cool fact is that Javascript has first class functions. This means you can
bring a lot of development patterns from the functional realm into your web
development.

There is a trend of languages moving away from the concept of mutable state.
The article does a good job with the first steps (by wrapping everything in
its own function scope), but Javascript lets us go further. The article seems
like it attempts to shoe-horn the concepts of classes and sub-type
polymorphism into a language that has better options.

~~~
alttab
One time I saw a some code where the author re-implemented haskell in
javascript. Needless to say reading that code was nearly impossible!

------
TimJRobinson
This is the kind of article I really needed to read 18 months ago instead of
fumbling my way through it by myself.

It's amazing how few tutorials there are out there that fill in that gap
between being a traditional web developer versed in .net / php and knowing the
basics of javascript to being an actual javascript coder.

Most articles and tutorials around the web seem to target the beginner while
most hacker news front page pieces target the advanced coder who already
understands closures / prototypes etc and there seems to be very little in
between.

------
beambot
I'm not a Javascript developer... but that IIFE syntax strongly reminds me of
LISP.

 _(function(){//do some work})();_

~~~
MBlume
My "breakthrough moment" with Javascript was realizing that I could just treat
it like scheme.

------
aymeric
What is the difference between using the prototype technique shown in the
article and this?

var Person = function (){ this.Save = function() { … }; };

var person = new Person(); person.Save();

~~~
jamiemill
That's called a "privileged method". The advantage of those is that they can
access any private variables from the constructor, and they keep those
variables in scope for their lifetime.

The disadvantage however, is that the method is re-created once for each
instance when the constructor runs, so they are not as memory-efficient as the
prototype style.

Also, when you add methods to the prototype you affect all instances from the
past and the future. So for example if you add a method to String.prototype,
all current and future strings get it.

~~~
aymeric
Should I be concerned about the additional memory my way of doing things
takes? It seems more convenient, allows for private methods and a limited
drawback in my view (memory is rarely a bottleneck)

~~~
jamiemill
Probably depends on your application. You may also see slower construction
time if you are creating thousands of objects.

I think which to use depends on whether you believe private methods/variables
are helpful or not. Some argue they are unnecessary and it's better to keep
everything public. Some like to use a naming convention like an underscore
prefix on private items, but declare them publicly.

You could also argue that private items are problematic if you start composing
classes from other classes by extending. Then the new methods can't access the
private state because they're in a different scope, whereas if they were on
the prototype they could find it through `this`.

I've used both approaches but nowadays tend towards the prototype style as
that seems to be the more accepted.

~~~
esailija
There are also other problems such as nesting functions inside other functions
inside other functions which is IMO much harder to maintain than a clean flat
list of functions defined in the prototype. Don't even get me started on using
"self", "that" or "me" instead of the built-in keyword "this".

It could be just me but I cannot understand how that was/is/has been
acceptable at all in the first place. Doesn't functions nested 11 levels deep
(true story) ring any alarm bells for people?

------
bazzargh
I'd be interested if one of these articles on modularity also addressed
testability. For example, the IIFE pattern in the article:

(function(window, $, undefined){ //do some work }(window, jQuery));

If instead of immediately executing this function, we kept a reference to the
function, _then_ reference it, the function can be supplied with mocks for
testing. Obviously there's an issue that you'd pollute the global namespace
with this named function. So what's the best practice there?

~~~
ufo
I don't think you need to go through all the trouble. Some thing like the
following should be enough:

    
    
        oldJQuery = jQuery;
        jQuery = mock;
    
        //Run module
    
        jQuery = oldJQuery;
    

Remember that IIFE's are basically equivalent to variable definition and
assignment. The only reason we even have to go through the trouble of using
them is due to JS not having block scope.

~~~
bazzargh
Yeah, I'm aware I can do that, but it gets a bit painful for code that is
stateful & executes on load (like IIFE does). You end up having to write a
separate test script to run in a separate process for each test case...way
slower than if you can isolate the module and 'restart' it in a closure for
each test.

A different approach that might work for me would be to subvert require.js, so
that it pulls in mocks. I see there's other people thinking along the same
lines: <https://github.com/tigbro/requirejs-factory-plugin>

------
SonicSoul
great post, thanks.

i also highly recommend using popular frameworks and libraries, since lots of
them use the tricks mentioned in your article.

Another thing that's worth noting is the JSON Object Notation:
[http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Obj...](http://www.hunlock.com/blogs/Mastering_JSON_\(_JavaScript_Object_Notation_\))

very readable form of declaration.

~~~
Hovertruck
"JSON Object Notation" => JavaScript Object Notation Object Notation

~~~
lucianop
<https://en.wikipedia.org/wiki/RAS_syndrome>

------
MatthewPhillips
> Spy.prototype = new Person();

Don't do it that way. If the Person constructor assigns any data, for example
an array, that data will be shared with all instances of Spy. Most likely you
don't want that. Instead call the Person constructor within the Spy
constructor:

    
    
      function Spy() {
        Person.apply(this, arguments);
      }
    
      Spy.prototype = Person.prototype;
      Spy.prototype.constructor = Spy;

~~~
insin
Person will also have anything you add to Spy's prototype if you do that.

Attaching the "parent" prototype you want to have in the "child" prototype
chain to a dummy constructor and new-ing that will do the trick for widest
compatibility, although Object.create in ES5 and __proto__ (standardised) in
ES6 both give you more direct access to the prototype chain:

    
    
      function inherits(child, parent) {
        var dummy = function() {}
        dummy.prototype = parent.prototype
        child.prototype = new dummy()
        child.prototype.constructor = child
      }
    
      function Spy() {
        Person.apply(this, arguments)
      }
      inherits(Spy, Person)

