
Tips to Become a Better JavaScript Developer - jchmura
http://justinchmura.com/2014/08/20/become-a-better-javascript-developer/
======
makkerdam
Second example in tip #2 is dead wrong. JavaScript does NOT do Dymanic
Scoping.

I suspect he didn't even bother to run the code. His example throws an error
when I try it: "ReferenceError: x is not defined" (as expected).

blind-leading-the-blind etc.

~~~
Bahamut
The first example is wrong as well I believe - there is never a function call
of bar.

~~~
dmak
I came here to say this.

------
DiThi
The author should test their own examples

    
    
        var $ = document.querySelectorAll;
    

That doesn't work, it throws `TypeError: 'querySelectorAll' called on an
object that does not implement interface Document.` The correct line is:

    
    
        var $ = document.querySelectorAll.bind(document);
    

I know this well because I use it in all my JS projects and plays nicely with
Python style for loops (e.g. in CoffeeScript).

While I avoid jQuery I awknowledge the value of it, esp with old and mobile
browsers. I avoid it precisely because my apps need modern HTML5/WebGL capable
browsers anyway.

------
jasonlfunk
I dislike when people say that good developers don't use libraries like
jQuery. The main reason I use them is because I'm lazy. I'd much rather write
$("#id") than document.getElementById("id"). I rarely write any javascript
code that is so resource constrained that the extra time added by jQuery is
not acceptable.

~~~
enraged_camel
The actual quote was:

>>What I’m saying is don’t rely heavily on jQuery, or any other library,
without having some sort of understanding of how that library is accomplishing
it’s tasks.

Which I think is fair. (However, I don't agree with his assertion that using
vanilla JS will be more efficient - in most cases, it won't.)

~~~
Bahamut
Vanilla JS is more efficient than jQuery a lot of the time - for example,
consider the $(...) api - this has to do string parsing before it makes its
selector call, which by its very nature take away computing power.

These days it is negligible though. The argument for using jQuery for DOM
manipulation is oftentimes just one of readability.

~~~
pkorzeniewski
In 99% cases the performance difference doesn't matter - users won't notice
that a jQuery method runs 5ms slower than it would run in vanilla JS, but they
will notice if the script doesn't work at all, because your vanilla JS code
fails on older browsers.

~~~
Bahamut
I agree for the most part - I'm just making a theoretical distinction.

------
Xelom
Tip #4 Ditch the jQuery Crutch: "If you can accomplish the same thing by using
vanilla JavaScript, 90% of the time, it’s more efficient to do so."

No. Just no. It is not more efficient to do so 90% of the time. jQuery is
mature and battle proven. It is already doing what it can do with an efficient
way, which comes with years of experience.

Saying, write your vanilla javascript and ditch jQuery, your implementation
will be more efficient, is a no-no. Especially in javascript world!

~~~
woah
The statement about jQuery being more efficient may have been true about some
handrolled for loop selector engine in ie7, but modern browsers have the tools
we need now.

You can replace most uses of jQuery by aliasing querySelector to $ and
querySelectorAll to $$. You lose some of the automatic array iteration stuff,
but really, if you were writing good code you would know how many elements you
are about to select.

jQuery is a gigantic dependency and it's kind of sad if you need that crutch
to write js. Beyond the selector stuff, its promises and xhr stuff is dubious
as hell and can be done much better by several node.js libs like superagent
and async.js or bluebird.js.

jQuery goes in direct opposition to a composable module-based approach,
because it is a massive dependency.

~~~
woah
Downvote away, but if you've got to load 90kb to alias $, damn.

------
spion
I wrote an article about `this` [1], where I try to explain it in painstaking
detail, and the best way I found to explain it was as "the argument which is
passed to a function by placing it left of the dot"

[1]
[https://gist.github.com/spion/7180482](https://gist.github.com/spion/7180482)

------
aaronem
Shouldn't this be titled something more like "five things every competent
Javascript developer must know"?

~~~
Tloewald
No, because I think one of them is kind of wrong (you can be competent and
still use jQuery) and three of them are better off replaced by "use jshint".

Also, you'd be surprised how many otherwise competent javascript programmers
don't understand _this_ and simply avoid it most of the time. Heck, I wrote
some pretty ridiculously awesome (and robust) stuff without really
understanding _this_ , and it's quite possible someone telling everyone they
need to understand _this_ , doesn't.

~~~
RBerenguel
99% of the time I can, I avoid this. Only use it when it's the cleanest way to
do something... Avoids a few headaches. Of course, this is also helpful, and
when it is, it's great.

------
arnarbi
Author, please correct this article or put a disclaimer that it is not
authoritative. There is a certain responsibility in publishing articles like
this; since, for example, your (false) explanation of scoping is likely to
waste a lot of time for many people.

------
dkyc
_" You can write your own basic jQuery by doing this:

    
    
      var $ = document.querySelectorAll;
    

Obviously this won’t cover everything, [...]"_

wat

~~~
moron4hire
It's not even right for what the article author is trying to do. Or in other
words, s/he just broke their own rule #1: understand "this".
"document.querySelectorAll" must be called on the document object, and
reassigning it to a variable like this will make it be called in whatever
function scope it's currently in. To even get this to call correctly, it needs
to be "var $ = document.querySelectorAll.bind(document);"

~~~
TheZenPsycho
>> "document.querySelectorAll" must be called on the document object, and
reassigning it to a variable like this will make it be called with "this"
assigned to the global object, or "undefined" if you're using "use strict"

fixed.

------
m90
Didn't know that `var $ = document.querySelectorAll;` will give you a
chainable and highly fluent API, if I only knew earlier....

~~~
alessioalex
Yeah, it will also give you an array as the result. #not

~~~
moron4hire
it won't give you anything, calling that $ function will result in an error in
all but stupidly rare cases. And by stupidly rare I mean, it's rare to see
anyone use "with", and it'd be stupid to do "with(document)"

------
jchmura
Hey everyone, author here. I first want to say, I appreciate the feedback.
This is my first article that I think people have actually read and going
back, I saw all the mistakes that you guys did. I've gone through and done
some edits.

I apologize for the inaccuracies. I was just looking to help some beginner
JavaScript developers.

------
mekane8
Read "JavaScript: The Good Parts" by Douglas Crockford instead of this
article. It has all the information this article attempts to explain but
written much more clearly and accurately.

------
synandplay
Second example of second tip is a lie

------
moron4hire
Don't think of "this" as having weird rules with strange edge cases about what
it defaults to in certain scenarios. It is always dependent on how you call
the function, and there are only two rules, depending on your situation.

    
    
        1) "this" is whatever you set it to with call/apply/bind, or, if you didn't,
        2) if you're using "use strict"
        2.a) "this" is whatever is to the left of the dot when you call the function.
        2.b) otherwise, "this" is wherever you got the function from. 
    

Think of 2.a in the literal sense, if you called the function from a bare
variable reference with no dot operator on an object, then the statement
"whatever is to the left of the dot" is "undefined". Basically, this means
that you generally shouldn't end up with "window" as "this".

So, if you got a function from the global scope, it's "this" is in the global
scope. If you got it from an object, it's "this" is that object.

    
    
        function AClass(){ this.id = "bar"; }
        AClass.prototype.func = function(){ console.log(this.id); };
        var id = "foo";
        var obj1 = new AClass();
        var obj2 = {id: "baz"};
        var func = obj1.func;
        obj2.func = obj1.func; // or even just "func"
    
        console.log(func === obj1.func, func === obj2.func, obj1.func === obj2.func);
    
        func();      // prints "foo"
        obj1.func(); // prints "bar"
        obj2.func(); // prints "baz"
        with(obj1){ func(); } // prints "bar"
        with(obj2){ func(); } // prints "baz"
    

Same exact function in all cases. The reason func's "this" in the first of the
last three calls is "window" is not because that's what "this" defaults to,
it's because that's where we found "func".

Think of the global scope in a browser as looking something like this:

    
    
        function window(){
            with(this){
                // your code
            }
        }
        window.call(window);
    

So that is why, when an event handler is executed, it's "this" is the DOM
element to which the event handler was added.

    
    
        myButton.onclick = function(){
            // do something
        }
    

You just stored the function on the myButton object, so when it gets read back
again to be executed, it's coming from myObject.

Using addEventListener does the same thing. And if the browser vendors don't
actually store the event callbacks in the object, then I guess they must be
using "call" to maintain backwards compatibility with the old event wiring
syntax.

------
couchand
To these I would add: "test everything".

------
n0body
only needs one point, "only use javascript when you have to, it's a terrible
language and best avoided"

~~~
dmak
Why do you think its terrible?

~~~
n0body
the + operator, is it concatting strings, or adding? who knows.

the scoping sucks, e.g.

    
    
      (function() {
        var x = 1;
        console.log( x );
        if ( x ) {
          var y = 2;
        }
      
        console.log( y );
      })()
    

why is y defined? its being called out of the block it was declared in?

there's no proper foreach using other files is an effort and requires hacks to
get them loaded. callbacks everywhere. variable names as object keys is a pain
regex is a pita

i just don't like it, i have no idea why it's become so popular recently, i
can understand it runs in the browser and everyone has a browser, but why
server side stuff?

but whatever, each to their own i guess

~~~
nhenezi
> why is y defined? its being called out of the block it was declared in?

Javascript doesn't have block scope; above example is equivalent to:

    
    
      (function() {
        var x, y;
        x = 1;
        console.log( x );
        if ( x ) {
          y = 2;
        }
      
        console.log( y );
      })()
    

Variable declarations are always hoisted to the top of containing scope.

