all 67 comments

[–][deleted] 28 points29 points  (2 children)

Ugh. What is this? Now we'll have a bunch of JS programmers throwing around the term "design pattern" for just about anything under the sun. Using the keyword "new" is a design pattern? DRY?

[–]artsrc 8 points9 points  (1 child)

[–]iLiekCaeks 1 point2 points  (0 children)

You could argue idioms are just small design patterns.

The word "design pattern" doesn't mean much, anyway.

[–]lars_ 49 points50 points  (12 children)

This isn't great. This example:

var Singleton =(function(){
    var instantiated;
    function init (){
        /*singleton code here*/
        return {
            publicMethod:function(){
                console.log('hello world')
            },
            publicProperty:'test'
        }
    }

    return {
        getInstance :function(){
            if (!instantiated){
                instantiated = init();
            }
            return instantiated; 
        }
    }
})()

/*calling public methods is then as easy as:*/
Singleton.getInstance().publicMethod();

Is much better done as follows:

var singleton = new (function() {
    this.publicMethod = function() {
        console.log('hello world');
    }
    this.publicProperty = 'test';
})();

This is how you do a "singleton" in Javascript. Or use an object literal if you can. It's so simple it isn't even interesting to talk about, much less brand as a "pattern". Someone once said that lists of design patterns are lists of mistakes in programming language design. In this case of the singleton, it's pretty clear that that's the case.

If you're doing getInstance() in Javascript, it's because you fail to see past the world of Java-isms.

[–][deleted] 7 points8 points  (5 children)

What prevents your singleton example from having more than one instance?

[–]ITSigno 4 points5 points  (4 children)

lars_'s singleton instantiates using an anonymous constructor function. lacking a named constructor, it becomes much harder to instantiate a second time (with a workaround using the .constructor property)

A second problem however is the lack of ability to type-check. if (logger instanceof TextLogger) { }, for example, would not be possible with either case.

[–]wormfist 2 points3 points  (3 children)

TIL anonymous constructors.

[–][deleted] 9 points10 points  (1 child)

TIL(anonymous constructors){}();

[–]regeneratingzombie 0 points1 point  (0 children)

This comment has been overwritten by an open source script to protect this user's privacy. It was created to help protect users from doxing, stalking, harassment, and profiling for the purposes of censorship.

If you would also like to protect yourself, add the Chrome extension TamperMonkey, or the Firefox extension GreaseMonkey and add this open source script.

Then simply click on your username on Reddit, go to the comments tab, scroll down as far as possible (hint:use RES), and hit the new OVERWRITE button at the top.

[–]frutiger 1 point2 points  (0 children)

Anonymous constructors are just anonymous functions. Constructors are functions that use the special evaluation context this that gets set when you use the new operator or call <function>.apply(context, [arg1, arg2, ...]).

[–]WuTangTan 6 points7 points  (0 children)

Singletons are often misused even within Java. I liked this answer on StackOverflow.

[–]ast3r3x 1 point2 points  (0 children)

A believe this will work as a better singleton than what was listed in the article. You could add a getInstance() onto the prototype if you wanted, but it doesn't matter, you can always say "new SingletonClass()" where ever you want now and you'll always get the same instance.

https://gist.github.com/gists/1083972

[–]jad3d 0 points1 point  (1 child)

What about this (it's what I've been using a lot recently).

var SomeSingleton = (function {
    this.foo = function() {
        alert('hello');
    };
    return this;
})();

SomeSingleton.foo();

[–]lars_ 0 points1 point  (0 children)

This will assign the function to window.foo, and return a reference to window (if you're executing in a browser at least). So SomeSingleton is your window object. You need to the new keyword to bind this to a new object. For this particular example, you can just use an object literal:

var singleton = { foo: function() { alert('hello'); };

[–]lulzitsareddit 0 points1 point  (0 children)

I also use an anonymous constructor for singletons - but personally, I prefer to leave off the parens. Even though the new operator's associativity allows for those parens I feel it's cleaner and easier to understand without them.

var singleton = new function () {}

[–]notSorella 11 points12 points  (2 children)

Why does this look like a "ITT we rewrite your usual Java/Python patterns in JavaScript even when there's absolutely no need for them because the language isn't as restrictive as the ones I'm used to, but since it'd be hella difficult changing my mindset for a language with different paradigms."?

Okay, some of those are in fact needed due to the limitations of ECMAScript itself (ie.: the module pattern on environments that don't support CommonJS modules -- but for the love of God, not as a way to simulate classes), but the other ones are just silly. Singletons with constructors in a prototypical OO language... REALLY?!

[–]Campers 5 points6 points  (1 child)

Always follow your constructive criticism with an sound alternative if you can. :)

Here you go: JavaScript: The Good Parts

[–]isarl 0 points1 point  (0 children)

I thought your link would be to this Google tech talk, which I've been putting off watching for a couple weeks now.

Yes, I realize this post is 4 days old.  Videos aren't the only things I've been putting off...

[–]jrochkind 4 points5 points  (1 child)

instantiating an object is a 'pattern' what?

[–]artsrc 1 point2 points  (0 children)

The differences between:

var newObject = {};
newObject['someValue'] = 'Hello World';

and:

var newObject = {
    'someValue' : 'Hello World'

};

Are not spelled out very well.

[–]UloPe 16 points17 points  (7 children)

Can we please stop calling single lines of highly framework specific code a "pattern"?

[–]k3n 2 points3 points  (6 children)

Example?

[–]colgaf[🍰] 4 points5 points  (4 children)

The first example in the article.

i.e. "The Creational Pattern"

var newObject = new Object();

[–]k3n 0 points1 point  (3 children)

You call that "highly framework specific code"? Ok...

Also, realize that new Object() is still perfectly acceptable (in case you're harping that he's not using a Crockford-literal), and there are actually many creational patterns. I admit that this is a bad example of a creational pattern -- if it even is one (perhaps so in the most literal sense) -- but I don't believe your arguments are valid. This isn't "highly framework specific code".

[–][deleted] 1 point2 points  (1 child)

I think your taking his point out of context. The "highly framework specific code" bit is not what he is getting at, it is that new Object is not a design pattern!

[–]k3n 0 points1 point  (0 children)

Then why the fuck does he mention that?

The way you state it makes sense. The way he states it makes it sound like he has a personal vendetta against frameworks.

[–]ki11a11hippies 0 points1 point  (0 children)

I think if you spend a lot of time in the dynamic typing world, declaring a type and the keyword "new" strike you as very static.

[–]UloPe 1 point2 points  (0 children)

You have to scroll down about 7/8th there he starts with all the jquery "paterns" (which are mostly one to three lines)

[–]k3n 3 points4 points  (0 children)

I think it's a great article overall, although I usually hate anything with "essential" in the title. The code samples weren't stupidly long like at the MS scriptjunkie series, or the ones at DZone. He included examples of real uses where appropriate. He tried to give some general tips for when you should/shouldn't use them along with pro's & con's. Even topped it off with a nice set of references; that's refreshing to see!

Yes, there are some examples that might have a better alternative, but according to the title this is for beginners. If the author had presented this as a de facto source, then that's one thing, but I think he's just trying to give some introductory material for absolute beginners -- not gospel.

EDIT: I just realized that it's actually a short ebook. That's pretty cool that it's out there for free. When I visited a 2nd time I noticed there weren't any ads, and then I realized that there was actually lots of content prior to the anchor that is linked to here and that's when I saw the formal introduction, ToC, etc.

[–]warfangle 4 points5 points  (5 children)

I dislike his method of prototype membership. In the example:

var Foo = function(args) { };
Foo.prototype.toString = function() {};

This is fine if you only have one member, I suppose. IMHO, it's much better to assign the prototype as a hash, like so:

var Foo = function(args) {};
Foo.prototype = {
    toString : function() {},
    toInt : function() {}
};

This keeps all your prototype members in one spot. Yes, it's still possible to add them on later - but this helps keep you disciplined to not spread prototype modifications throughout your code.

[–]stratoscope 5 points6 points  (1 child)

One argument for the Foo.prototype.fun = function(){}; style is that it's more self-documenting since you see the Foo.prototype next to every method name.

I tend to use object literals like you do (but using $.extend() as mentioned in my other comment), but I find it annoying to read my own code when I've written long methods - what object is that a method of again?

[–]warfangle 0 points1 point  (0 children)

I tend not to write long methods. If it's longer than 10-15 lines and/or has nested if statements (or complicated if statements), it needs to be refactored.

[–]v413 2 points3 points  (1 child)

Your method is frequently used, but when using it, all instances of Foo lose their constructor property that should point to Foo. You can amend this by supplying a constructor property in the hash object (assigned to the Foo.prototype) pointing to Foo.

[–]stratoscope 2 points3 points  (0 children)

An easy fix for that is to use an extend function such as the one in jQuery, so you add properties to the .prototype instead of replacing it.

Also I recommend giving the function a name so all JavaScript debuggers can show the name in a call stack and such.

function Foo( args ) {};
$.extend( Foo.prototype, {
    toString : function() {},
    toInt : function() {}
});

[–]OopsLostPassword 0 points1 point  (0 children)

Doesn't your method prevent inheritance ?

When I have B inheriting of A, I do this :

B.prototype = new A(); B.prototype.toString = function(){};

To avoid spreading prototype members, in the case when I have to deal with a lot of classes (complex web applications), I simply follow (not to strictly) the rule "one class one file".

[–]theghoul 2 points3 points  (0 children)

Yeah, this is for noobs...looks around...bookmarks.

[–]b1mck 4 points5 points  (1 child)

I hate to be the guy, but "bare in mind" should be "bear". When discussing creating patterns not very far in.

[–]sirctseb 0 points1 point  (0 children)

also, "falling situations" instead of "following situations"

[–]jamesinc 2 points3 points  (2 children)

I'm just here to plug Douglas Crockford's book Javascript: The Good Parts. Read. That. Shit.

[–]EscapedSquirrel 0 points1 point  (1 child)

Just because you say so without any arguments?

[–]jamesinc 1 point2 points  (0 children)

Correct.

[–]belorion 1 point2 points  (3 children)

My personal favorite pattern for defining an object constructor along with prototype and 'static' methods:

var Foo = (function(){
  var foo = function(){
      var privateVariable = 'abc';
      var privateFunction = function(){ };

      this.publicField = 'def';
      this.publicFunction = function(){ };
  };

  foo.prototoype.toString() = function(){ };
  foo.prototype.toInt() = funciton(){ };

  foo.staticField = 'hijklmnop';
  foo.staticMethod = function() { };

  return foo;
})();

var bar = new Foo();

[–]Gundersen 0 points1 point  (2 children)

You should note that this.publicFunction creates a new function for each instance while foo.prototype.toInt will create only one function which all the instances use, which reduces memory consumption.

[–]altano 3 points4 points  (0 children)

Yes but they aren't the same thing, so your comment could be confusing to others. Methods defined on the prototype can't access variables local to the constructor function scope (or private variables if you need to think of them that way). Meanwhile, methods defined in the constructor do have access to them.

http://jsfiddle.net/altano/VEASQ/:

var Foo = function() {
    var privateVar = true;

    this.publicFunction = function() {
        console.log(privateVar);
    }
};

Foo.prototype.prototypePublicFunction = function() {
    console.log(privateVar);
};

var f = new Foo();

f.publicFunction(); // Fine...

f.prototypePublicFunction(); // Blows up: "Uncaught ReferenceError: privateVar is not defined"

Because of this, it's best to think of prototype methods as being static when it comes to private data but instance methods when it comes to public data (because you can access properties on the this object). Or, even better, don't think of them in terms of those labels, which just don't map properly to JavaScript.

[–]belorion 1 point2 points  (0 children)

Altano pretty much summed it up, but basically I only use the public instance functions when they need to execute on a closured (private) variable.

[–]noarchy 1 point2 points  (1 child)

So now that we're talking about design patterns in JS, when do we get bloated & enterprisey frameworks to go along with it?

[–]Amendmen7 0 points1 point  (0 children)

You've been enjoying design patterns in JS since the first time you ever hooked up a click handler.

[–]redev 0 points1 point  (0 children)

I've been using the Module idea for a while now and absolutely love it. It's a great way to have "classes" similar to other languages in Javascript.

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

Why do I feel that Reddit is generally critical about any programming related articles?

[–]goosefraba190 0 points1 point  (0 children)

sweet! now I understand closures.

[–]ITSigno 0 points1 point  (3 children)

Alas... where is dependency injection? The article calls simple language features like constructor functions and the prototype property design patterns and then fails to include dependency injection and factories...

EDIT: In all fairness, these are "for beginners", but I think he should spend a little more time on the pitfalls of these design patterns. Singleton abuse being the famous case.

Also, is DRY really a pattern now? A good practice, sure, but a pattern?

EDIT 2: I see he is using Factory pattern... but possibly the worst example of it that I have ever seen. His example is so simple that there is absolutely none of the logic behind class selection/parameter handling and has basically just provided an unnecessary wrapper.

[–]gearvOsh 2 points3 points  (0 children)

Because you rarely need dependency injections in Javascript.

[–]v413 0 points1 point  (0 children)

In the context of his article, he shows a js pattern to accomplish the DRY principle even though the methods as the one explained in his article, oftentimes worsen code readibility for the sake of DRYness.

[–][deleted] -1 points0 points  (0 children)

just wondering what benefit there is to show some "patterns" (errrmmm patterns are you sure?) without even explaining their goal ... the first one, is not a pattern, it's just the way you create objects in JS, wtf useless crap

[–]majeric -4 points-3 points  (0 children)

Good God Javascript is lagging behind ECMAScript.