

Why You Should Always Use === and Other Bad Practices - adamnemecek
http://fifod.com/why-you-should-always-use-and-other-bad-practices/

======
JelteF
This illustrates way better what is wrong with that piece of code:
[http://stackoverflow.com/a/500531/2570866](http://stackoverflow.com/a/500531/2570866)

The speed shouldn't be the issue. If it is, please start using a library like
Lo-Dash [1], a faster version of Underscore.js. Actually, please just do that
in general so you won't make mistakes like this.

[1] [http://lodash.com/](http://lodash.com/)

------
jpatokal
I'd draw an entirely different lesson from this -- namely, killing time by
doing "100 other minor cleanup changes to a bunch of different files" on a
40,000 LOC legacy production system that (apparently?) has no tests sounds
like a Really Bad Idea(tm). Don't mess with code you don't understand if you
don't have even the basic safety net of decent unit tests in place.

------
goldenkey
I am scratching my head at how someone can write a blog post correcting code
and leaving such egregious code as a revision. The last snippet of code is
still busted and very cringeworthy

The proper way to do alternate behavior for the first iteration, would be
this... It's O(n) versus the authors O(2n)

    
    
        if(attributeArray instanceof Array) { 
            if (attributeArray.length >= 1){
                // do something with attributeArray[0]
                for (var i = 1; i < attributeArray.length; ++i) 
                    // do something different with attributeArray[index]
            }
        }

~~~
inglor
Not to mention the anti pattern of doing this in the first place.

When manipulating collections - you almost always want .map .filter .reduce
.some .all or a variation of thereof and not a plain old for loop for this
sort of thing, doing this a million or a billion times a second theoretically
shouldn't matter. (explained in :
[http://stackoverflow.com/a/17253577/1348195](http://stackoverflow.com/a/17253577/1348195))

Also, checking for instanceof Array is a JS anti pattern to begin with and
makes code a lot less generic.

~~~
goldenkey
I agree that the Array methods are extremely useful other than their ugly
performance-sacrificing function scope. In this case though, when you need
alternate behavior for the first index, it is much clearer to read a standard
for loop with some precursor code behind it, than to read a forEach loop with
an if-else.

~~~
inglor
Really? You find the above loop more readable than:

    
    
        if(array.length > 0) doFunction(array[0]);
        array.slice(1).forEach(doOtherFunction);

~~~
goldenkey
You're kind of cheating because you're using slice which will create a copy of
the Array, and that's not cheap if the array is large.

~~~
inglor
People use arrays for things like queues and stacks all the time in JavaScript
- they're _much_ slower than hand rolled collection (eg.
[http://jsperf.com/deque-vs-array-2](http://jsperf.com/deque-vs-array-2) ) -
why not micro optimize that as well?

If you have a very large array of course optimization can/should be considered
but that's simply not the average case.

~~~
goldenkey
I actually like the slice code for it's ease of readability. Functional
methods are extremely nice and I hope they get faster and faster with the
optimization of JS JITs.

I never heard of Dequeue [1], that is mighty cool. I agree that premature
optimization is not good - but when it can be done cleanly without hurt to the
readability of the code, I'd say to keep it in ones' repertoire, to
effectively write more performant code, more often, on average.

[1]
[http://code.stephenmorley.org/javascript/queues/](http://code.stephenmorley.org/javascript/queues/)

------
dcherman
That code snippet is also using a faulty technique for identifying an Array.
Although it will work for the majority of cases, if you're using an array from
a different iframe, the instanceof check will fail since the Array
constructors are not the same.

You should be using Array.isArray ( ES5 compatible browsers ), or
Object.prototype.toString.call( obj ) === '[object Array].

Lodash, Underscore, and jQuery all provide utility methods to do that
comparison for you.

~~~
inglor
Should probably do `.length` to detect it's iterable and not do a type check
since that's an anti pattern anyway.

~~~
underwater
That would happily accept and iterate over a string, which wouldn't be
desirable.

------
727374
Also, putting 'var' in a loop header is debatable because it gives the false
impression that the variable "i"'s scope is confined to the for loop, when in
reality it will be alive throughout the containing function. JSLint would
bark.

~~~
xiaoma
I don't think it gives that impression at all.

In JavaScript the rules for scope are clear—it's lexical scoping nested at the
function level. Loops, conditionals, etc... have no bearing on scope.

------
al2o3cr
Better title: "Why Javascript's for/in loop is more useless than a sack of
busted assholes".

~~~
inglor
Also, Object.keys is much nicer and doesn't have a lot of the same issues.

------
shawnz
The only problem here was that a for/in loop was being used. Iterating the
array, rather than its properties, was clearly what was actually wanted.
However, the author uses the opportunity to take a strong stance in favour of
always using strict equals, even though it was never a bug here anyway. As far
as I can see, the only argument this article produces against double equals is
that overzealous developers might accidentally break your code trying to be
proactive.

Strict equals is something I only use when necessary in javascript. Despite
the "taboo" surrounding double equals, I rarely face situations where its use
adds brittleness to the code. Is there some horrible danger that I am just not
seeing?

~~~
magicalist
Well in this case, the original author was relying on '0' == 0 for their code
to work. Even if you were dead set against using strict equality (which is
silly, but whatever), the code is still disingenuous and should have tested
index == '0' to make its intent clear. There's no other value that they could
have being relying on it to coerce without some other very nasty things going
on.

> _overzealous developers might accidentally break your code trying to be
> proactive_

It's not just people changing your code, it's people trying to read your code
(including you, months later).

------
inglor
That's stupid, the reason you should not use `for... in` isn't because it's
slow, it's because it's reflective.

It's using reflection over object keys to iterate an array. This just happens
to work because JavaScript arrays are also objects.

`myArr.forEach(function(el){ // do things here });`

Is perfectly fine.

~~~
inglor
Also,
[http://stackoverflow.com/a/17253577/1348195](http://stackoverflow.com/a/17253577/1348195)

------
ndesaulniers
I'd recommend putting comments around code that appears like it may be wrong,
or just avoiding such code as proposed. For instance, if I must do assignment
within a conditional, I would at least put a comment the line before saying
that assignment was intentional. But it's worth writing the assignment on its
own line for clarity.

------
joshguthrie
Why you should not use "should" or any other imperative in your HN
contributions if you don't want to be downvoted to hell and back.

------
AeroNotix
garbage in, garbage out.

~~~
goldenkey
JCVM sure has some issues (Javascript Coder Virtual Machine)

------
himal
Is it me or the title seems to suggest the use of '===' considered as a bad
practice ?

