
Real-World JavaScript Anti-Patterns - StylifyYourBlog
http://blog.javascripting.com/2014/11/06/real-world-javascript-anti-patterns/
======
ufo
I disagree on

    
    
        items.forEach(function(item) {  
            doSomething(item);
        });
    

being an anti pattern. Many of these looping functions actually pass more than
one argument to the callback, so writing

    
    
        items.forEach(doSomething);
    

will break if doSomething is a function with optional arguments.

~~~
mrspeaker
Yeah - not being aware of this will screw you up!

    
    
        ['10','10','10','10','10'].map(parseInt)
        // [10, NaN, 2, 3, 4]

~~~
marcosdumay
Several "wat!"s on that line... I didn't know "10" was a number in base 0.

~~~
Bognar
It gets even weirder:

    
    
        parseInt('10', {test: 'test'})
        10
    
        parseInt('10', 'test')
        10
    
        parseInt('10', '2')
        2

------
TillE
I'm not a Javascript developer, but I sort of disagree with the point about
forEach and thisArg. Using a closure like that is clearer than relying on some
custom magic done by a certain function.

Function.prototype.bind() makes sense, though.

------
osconfused
Anti patterns? To what specific style of development? Imperative programming?
functional? Class based / MVC / object oriented? Prototypical? This article
lacks clarity and draws no useful conclusions.

"so one obvious improvement would be to use selectors instead of the execrable
DOM API"

Additionally, DOM API is slow. Wrapping your access to the DOM in additional
layers of abstraction isn't a win or "anti pattern". It's a maintenance trade
off.

------
xtrumanx
I just realized how I learned to put to good use many of the above stuff when
using React. When I used to use Angular a common theme when I was writing my
code was "How do I accomplish my goal by using Angular's API (as opposed to
jQuery)?".

With React, since my "markup" and code is all just Javascript the common theme
has become "How do I accomplish my goal in plain old Javascript?". The skills
I've been picking up are definitely transferable to projects that don't use
React or any other JS library.

Though I do keep forgetting to add `.bind(this)` all the time that it makes me
miss using `var self = this;`.

~~~
EGreg
Forgetting to use bind can be a good thing. See my comment above.

As for writing things "the Angular way", it's about truly separating your MVC
layers using two way databinding. I don't care how you do it as long as you
keep V as declarative as possible. It sounds like "the javascript way" for you
might just involve a lot of storing data in the DOM.

I think a much more robust pattern involves:

A Model - This is Javascript data stored outside the DOM, for easy
manipulation. It is usually accessible via the window object

A ViewModel - This is Javascript data that is stored outsidd the DOM but is
referenced directly by a data-bound component. It can involve view
transformations such as time/date localization.

A View - This is the actual DOM component, in Angular it is a "directive". It
reacts to changes in the ViewModel and can also change the Model (which in
turn changes the ViewModel).

That way, for example, if you want to implement optimistic visual feedback you
can do it in the Model and have the model try to sync or revert.

All this becomes even more complex when you have to build multi user apps. You
can use Firebass or Parse etc. or you can check out
[http://platform.qbix.com](http://platform.qbix.com) \-- open sourced but
still a work in progress until 1.0

~~~
xtrumanx
> It sounds like "the javascript way" for you might just involve a lot of
> storing data in the DOM.

I don't think I've ever modified the DOM directly when using React. Try it
out, it's a really refreshing take on building client-side apps.

------
xg15
While I agree with most of the points he listed, I have an issue with the
style on which he presented them: In almost all cases, he presented the wrong
solution, followed by an alternative which is "obviously" better - without
explaining _why_ it is better. The map-with-side-effects example is even
worse, performance-wise than the original. Of course, performance tradeoffs of
this kind are usually acceptable, but you usually want to know what you get in
return. Especially in the for-each examples, this is not clear at all.

------
wpears
His second bind example is incorrect.

    
    
      function handleClick(i) {  
        this.innerHTML = i;
      }
    
      for (i = 0; i < elems.length; i++) {  
        elems[i].addEventListener("click", handleClick.bind(this, i));
      }
    

In the for loop, the _this_ value refers to the global object. To get the
desired effect, it should be changed to elems[i] (this piece of code is trying
to bind a handler to an element).

------
bitroliest
I was wondering why the author mentioned _.partial after a sections about
Function.prototype.bind. Wouldn't : _.partial(_.merge, {}).apply(this, confs);
Be the same as: _.merge.bind(_, {}).apply(_, confs);

That being said, I'm glad this forced me to look up _.partial - seems like you
can pass '_' as a parameter and that position in the arguments will not be
bound in the partial function!

------
mkoryak
They should mention that most of the functions they use and recommend using
don't exist in IE8 and crappier.

~~~
ben336
That's becoming less of an issue these days in general. But many of the
examples use underscore/lodash, which do in fact support old IEs.

------
EGreg
Some of these are good. Others, such as using .bind() just to create a handler
for the click() event, are terrible. Not only are you creating a NEW closure
every time the code runs (via executing .bind) but also you lose th ability to
use the actual _this_ inside the handler! Much better to use closures as they
were intended, and have that extra _this var to refer to the previous context
if necessary.

------
Bahamut
I disagree with the MyButton.prototype.new example - it isn't difficult to see
that it is an api, and usage of new to do something like button.new() makes
for very readable code.

------
serve_yay
There is good stuff here, but "anti-pattern" doesn't mean "you typed more than
you really needed to". Rather simple tools can fix that sort of thing.

------
jbeja
Using "this" is already an anti-pattern.

~~~
moron4hire
Only if you don't properly know JavaScript. Which is basically what this
entire article is about.

~~~
jbeja
Well JS is all about context, literally and figuratively I guess.

