

JS Adolescence: Change of opinion regarding certain JavaScript practices - niyazpk
http://james.padolsey.com/javascript/js-adolescence/

======
jrajav
Repeatedly used inline object literals:

Object literals are one of the best features of Javascript, learn to love
them. In the example cited, you already have a function dedicated to creating
this object; why would you need to further obfuscate it by delegating the
actual leg work to a buzzword-filled framework (or worse, vanilla
constructors)? Even for more complex examples, I find it clearer and simpler
to use an extend() or clone() method than something that tries to emulate
classes.

Strict equality everywhere:

You cherry-picked two simple examples, but normally it's more complex than
that. Javascript has rather odd coercion, and it will bite you if you try to
memorize all the cases where it's safe to use ==. It's not really that === is
"strict", it's just that it generally works how == was supposed to. More
importantly, though, there's never any harm in using === instead of ==, so why
would you use the latter? Why is === "overkill?" Because it's one character
more? I fail to see the argument for not using it, except to play the devil's
advocate.

Strict coherence to a standard:

This is a fine swing to take if you're doing hobby work, in fact it's very
healthy, but if you're working on any sort of larger project where you are or
will be collaborating with others, it is nothing short of essential to agree
on standards for everything from brace style to camel case to testing
frameworks. Almost every other argument concerning style, practices, and
idioms falls apart in favor of consistency.

~~~
pretoriusB
Re: strict equality everywhere.

If you "fail to see the argument for not using it", then you're not trying
hard enough.

Javascript was not designed with strict equality check in mind. The coercion
it does can be harmful if you don't know how it works, but it can be very
useful and liberating if you do.

Essentially, but restricting yourself to "strict equality" you make Javascript
a less dynamic language. Sometimes "20" is as good as 20.

Dimitry Baranovsky, of Raphael fame, wrote about this specific issue:

<http://dmitry.baranovskiy.com/post/typeof-and-friends>

------
pags
Why post this stuff? He offers opinion without explanation, this is the same
type of JavaScript "wisdom" that probably had him following the conventions he
is now nixing in the first place. I'm not sure if his "dogma" disclaimer at
the end is ironic or a cop-out.

~~~
amadeus
Agreed. This article is utterly worthless.

Why is this on the front page?

------
btipling
I disagree with abandoning one statement var declarations. This will bite you.
A variable declared with var is in scope for the entire function because of
hoisting.

It's also just bad form because of how people write Javascript, for example if
you have an unfortunately long nested function with a variable declaration
toward the bottom with a common name, say 'width' and later add that variable
name a level up in scope and then think to use it in your function because you
forgot or didn't know you had a var statement declaring width somewhere in
that function you'll have fun staring into the abyss when this runtime error
eventually presents itself.

~~~
aufreak3
I've had the other kind of trouble with this. While I've almost never had
trouble with code declaring variables near the site where they are first
needed, I've on quite a few occasions missed top-level declarations, perhaps
because I carried with me a memory of a declaration done in another function
(or something like that) ... resulting in major "global" catastrophes (sorry
;)

While I acknowledge that declaring vars within ifs/whiles and such can lead to
misunderstanding, declaring vars close to the site of first use at the top-
level block of a function has never resulted in a bug for me. This approach
also diffs better.

------
Xcelerate
I disagree with not using "inline object literals". They're basically maps,
and in fact some programming languages (e.g. Self) are built around the
concept of using maps instead of a list of arguments. I think in some cases
this can be beneficial. Much more so than SomeWeirdCall(0, 0, 0, 0, 0, 0,
NULL, "some data");

------
fourstar
Aside from inline object literals, and using strict equality (which you should
always be using IMO), what does this specifically have to do this Javascript?
Everything else applies to general programming.

~~~
error54
Agree. Most of the things would apply to (most) all languages such as avoiding
verbose comments and not using 1 word variable names. I fully disagree with
his stance on not declaring vars at the top of the scope though. It's a good
practice with any JIT compiled language as it's easy to declared the same
variable twice if you're not paying attention but it's a very hard mistake to
catch as it won't throw error. The reason for strict (read:Crockford)
conventions is that Javascript is an incredibly loose language thus it is very
easy make mistakes.

------
richforrester
Funny; I comment the living carp out of my JS.

Mainly because I suck at it (I'm a designer, not a developer, dagnabbit) and
it helps me keep track of what I'm doing.

Other than that, great article, taught me a thing or two.

------
kondro
Disagree vehemently with the idea that long variable names equate to bad API
design.

The more descriptive your naming, the better your design and the less comments
you require.

~~~
sosuke
Self commenting code!

------
ronaldj
Can someone explain how this is potentially dangerous?

if (!cachedReturnValues[key]) { cachedReturnValues[key] = value; }

~~~
Leszek
The condition will be true in any of the below cases:

    
    
      cachedReturnValues[key] === false
      cachedReturnValues[key] === 0
      cachedReturnValues[key] === ""
      cachedReturnValues[key] === null
      cachedReturnValues[key] === undefined (this is presumably the only desired behaviour)
      cachedReturnValues[key] === NaN

~~~
dagw
But surely all that happens in these cases is that the function gets re-
evaluated, leading to marginally worse performance in a few cases (for example
functions that return 0 a lot). Unless your function has side effects and it's
vital that it is only run once for each argument I can't think of a scenario
where that code is dangerous.

~~~
pretoriusB
> _But surely all that happens in these cases is that the function gets re-
> evaluated (...) Unless your function has side effects and it's vital that it
> is only run once for each argument I can't think of a scenario where that
> code is dangerous._

Then this kind of code would have blown in your face.

Besides the function being re-evaluated, the hash gets a NEW value "value" for
that key. Nobody ensures that "value" is the same as the one it was already
there.

E.g

var cachedReturnValues = {key: 0};

var value = 50;

if (!cachedReturnValues[key]) { cachedReturnValues[key] = value; }

So, instead of setting the value when the key is not already in the hash, now
we also CHANGE it in all these false-positive cases.

Furthermore, even if (a) the function had no side-effects, and (b) by some
magic the value was the same with what was already in the hash, e.g if your
wrong "merely re-evaluation" assumption was true, who would ensure that the
overall block has no side-effects?

if (!cachedReturnValues[key]) { cachedReturnValues[key] = value;
doSomethingElse(); }

Just because we see it written in a way that doesn't do much harm now, doesn't
mean it's not extremely dangerous to blow up in the future, e.g. when some
naive programmer adds another statement to the block.

------
calinet6
Here's a tip: you're still an adolescent. Come back in 5 years.

