47

My background is in C and I've picked up PHP, mySQL, HTML, CSS without too much issue.

But I'm finding Javascript/jQuery surprisingly difficult to get right. Very frustrating. Why?

  1. It seems to violate a number of traditional programming principles (e.g. variable scope)

  2. Undefined variables seem to appear out of nowhere and already have values associated with them. For example (from the jQuery docs):

    $("a").click(function(event) {
        event.preventDefault();
        $('<div/>')
              .append('default ' + event.type + ' prevented')
              .appendTo('#log');
    });
    

    What exactly is "event"? Do I have to use this variable name? Should I just assume that this object is magically instantiated with the right stuff and I can use any of the methods list at the JQuery API?

  3. There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)

  4. Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)

  5. Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.

It seems like everyday there's some random JS "rule" that comes up that I've never seen before in any of my JS books or tutorials.

What do I need to do to make Javascript/jQuery more deterministic, controlled, and logical to me?

Are there any resources that explain Javascript's quirks/gotchas?

Thanks!

harto
  • 89,823
  • 9
  • 47
  • 61
JMan
  • 1,815
  • 5
  • 21
  • 34
  • 18
    Yep, JS is a fickle mistress. But you forgot "6) Doesn't work the same across browser platforms." – iandisme Aug 03 '10 at 15:46
  • re "There seems to be bunch of random rules": yup, that's the fallout from the Browser Wars in the early 2000s. Everybody and their dog wrote their own, mutually incompatible JS extensions. – Piskvor left the building Aug 03 '10 at 15:47
  • 7
    You forgot "optional" semicolons :) – Nick Craver Aug 03 '10 at 15:47
  • 4
    Examples of #2, #4 and #5 please. Beware of the Crockford. – annakata Aug 03 '10 at 15:47
  • maybe you better learn javascript just as a base and get some experince. but there is no need to reinvent the wheel, learn jquery or mootools so you wont have to worry about cross browser stuff so much. and also work more with objects – guy schaller Aug 03 '10 at 15:50
  • 1
    See http://stackoverflow.com/questions/597630/understanding-javascript-resource/597772#597772 – Crescent Fresh Aug 03 '10 at 15:55
  • I don't mean this as self-promotion, but I wrote a post on javascript scope not too long ago. Many of your problems may be solved by a better understanding of the way scope works in Javascript, as it is function-based, not block-based. http://www.ryankinal.com/blog.php?pid=28 – Ryan Kinal Aug 03 '10 at 15:57
  • 4
    You can write messy code with any programming language. It is the fault of the programmer, not the language. – Felix Kling Aug 03 '10 at 16:07
  • I've added an example of #2 above. – JMan Aug 04 '10 at 05:21
  • Re: #2 - That is what is called an "event handler". It's a specific type of function that takes one argument (in most browsers): The event that triggered it. (A lot of non-js frameworks have this kind of function - referred to as a "callback"). Internet Explorer being the exception, rather than the rule, instead has `window.event`. It won't have all the same properties, as IE has its own proprietary event model, rather than the standardized one. http://www.javascriptkit.com/jsref/event.shtml – Ryan Kinal Aug 04 '10 at 12:10
  • 11
    @Felix Have you ever used JavaScript? It's a serious challenge to write code that isn't messy in JavaScript. It's the language. – Jeff Davis Aug 04 '10 at 21:01
  • @Jeff Davis: Of course I have used JavaScript. But lately I mostly used it to create an addon for Firefox so I don't had to deal with cross browser issues. But even that would be a failure of the different implementations of the browsers, not the language itself. I think the most important thing is to understand how the scope chain and closures work. Of course there are things that could be improved in JS. But if you *want* to write good code, you can do it nevertheless. It is easy to say *I cannot write good code with XY, because it does not allow it* ;) – Felix Kling Aug 05 '10 at 05:55
  • Re: Messy Code - I think JavaScript is at least as suited to pretty code as C, C++, PHP, Java, or any other C-style language. It's simply a matter of proficiency and coding style. Unfortunately, I also think jQuery leads to messy code - chaining, inline functions, etc. are not conducive to well-formatted and understandable code. But JavaScript is not to be blamed for that. In and of itself, I consider it a very expressive and aesthetically pleasing language. – Ryan Kinal Aug 05 '10 at 12:21
  • i used to curse tha days i had to do things in javascript, mostly because i was seeing it as a C++ / Java / Php which is not. i didn't understand the language and i was blaming the language instead of the DOM. Once i learned the basics (Crockford helped a lot) it all got a lot clearer. Now i'm loving it. i wish i could do all my work in javascript. Closures are a beautifull thing. I wish all the programming languages be more like javascript :). just my two cents – Vlad Balmos Nov 03 '11 at 19:30
  • Just always use var (if you need explicit global variable, use the global object properties) and semicolons, always declare variables like they are handled internally (hoisted to the top of the scope) and so on. I cannot believe someone actually thinks closures and first class functions are messy, when they actually allow more simple and elegant solutions to almost every problem. Nobody is forcing one to use them though and you can write procedural code if you wish. The DOM libraries, cross browser quirks and anything to do with the browser have nothing to do with the language itself. – Esailija Nov 10 '11 at 22:25
  • @JeffDavis I could not agree more with you. It's the language. Seriously try this: `function foo(a, b, c) { return true; } foo(4);` You don't even have to call a function with all parameters, just one is enough for example. It's a mess. – broadband Oct 19 '18 at 07:24

12 Answers12

12

1) It seems to violate a number of traditional programming principles (e.g. variable scope)

You need to declare variables using var, else it will go into the global scope.

2) Undefined variables seem to appear out of nowhere and already have values associated with them (how did this happen?)

This is possibly related to 1) and/or 4).

3) There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)

You need to let the handler return false as well. E.g. form onsubmit="return functionname()". You also need to return from the "main" function, not only from a closure (a function inside a function), referring to your previous question. It would only return into the "main" function and continue on.

4) Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)

Probably the code was executed before the HTML DOM was finished populating. You need to hook on window.onload or $(document).ready() whenever you want to execute stuff during page load.

5) Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.

I bet that you're talking about jQuery source? It's just a large library. You should after all not worry about this when debugging. Rather worry about your own code. However, make sure that you're looking at the unminified version of jQuery's source code.


See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
10

Douglas Crockford's "Javascript: The Good Parts" was an invaluable resource. Javascript plays a lot more like Lua, Lisp, or Python than C, it just happens to LOOK like C.

Link provided to Amazon; I snagged mine from O'Reilly.

Broam
  • 4,602
  • 1
  • 23
  • 38
  • That amazon link, "rads.stackoverflow.com/amzn/click/0596517742". What are you doing there? – Crescent Fresh Aug 03 '10 at 16:24
  • 2
    @Crescent I think SO automatically converts Amazon links to their ref. code. Good for them. – JAL Aug 03 '10 at 17:50
  • The Good Parts is an excellent language reference, great recommendation. It doesn't cover browsers, just the core language. – JAL Aug 03 '10 at 17:51
6

To be honest, I think you have a good understanding. Some of my hangups were similar. The way that I have been moving on is "well, if that's the way it is, then that's the way it is". Just accept the idiosyncrasies and plow forward. PHP does some of the same things (variables can show up out of nowhere, etc...). Just code the way you want to code and if it works, then great!

Then after you get to that point start breaking out the profiler and see if there's anything that you can optimize.

Here are a couple of things:

If you understand CSS, then jQuery selectors should be easy. As far as the code goes, that's straightforward too if you can deal with chaining and JSON. EDIT: also, the jQuery documentation on everything is EXCELLENT! And There is no shortage of jQuery experts here on SO to help us noobs (and hopefully we can return the favor for newer noobs).

There is a scope to work with. (Basically) anything written outside of a function or object is in global scope. If you are inside of an object or function and use var then that sets the variable's scope

Javascript isn't like a C-based language (C++ or PHP even). It uses prototypes to deal with class/object relationships rather than a subclassing scheme.

The #1 thing that threw me for a loop is that any JS that appears anywhere on the page or that was included in <script> tags is fair game. If you have a global variable in one script, you can use that same variable in a completely different script and it will work. That may be what you mean about variables showing up out of nowhere. Also, there are some DOM based variables that can just "show up" too.

Anyways, I think that if you just plow ahead, you'll get some "AHA" moments. I'm a relative noob to programming, but I continually grow as long as I don't hang up on something that doesn't have too much of an impact on actually making the code run.

TCCV
  • 3,142
  • 4
  • 25
  • 30
3
  1. It's a language based on prototypal inheritance and is influenced by functional programming languages and the paradigm so it isn't completely just OO/Procedural like other languages. Variables are implied globals unless declared with var.

  2. Please include an example?

  3. return false exits out of the function as with any language's return statement. preventDefault() would be the DOM method to cancel the default behaviour of a link

  4. Javascript is used primarily on the client side. Since there are many user agents, each of them have a different implementation of the DOM, which is very inconsistent, moreso than JS itself. Again, please include a real example to get a definitive answer.

  5. You'll find messy looking code in any language, and maybe your lack of understanding perceives the code as messy, when in fact it isn't so bad. Or maybe you're looking at some minified/obfuscated code.

I recommend http://eloquentjavascript.net/ for learning aspects of Javascript.

Things you'll learn from the link above

  • lambdas
  • closures
  • Prototypal inheritance
  • Event based programming
  • Debugging
  • DOM
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
2

"JavaScript: The Good Parts" by Douglas Crockford is a good start

In your case, the appendices ("the bad parts" and "the awful parts") might be the most interesting :)

Jakob
  • 24,154
  • 8
  • 46
  • 57
2

Crockford's "Javascript: The Good Parts" gives some common JS patterns that help with variable privatization and scoping. This is for javascript in general. For jQuery I just use the API. Also the Yui Theatre videos on javascript are quite good

brad
  • 31,987
  • 28
  • 102
  • 155
2

Javascript can be a little tricky and some of it's functional aspects confuses people. If you actually learn and understand the language you'll find it really useful, most people just randomly start using it and then just hate.

Read javascript the good parts by crockford, it's really helpful: http://javascript.crockford.com/

Also make sure you understand closure. It's a fundamental that people don't get but often use.

Ken Struys
  • 1,789
  • 1
  • 10
  • 17
0

In terms of variable scope, there are local and global variables. One of the gotchyas of variable scope can be seen in this example:

var thisIsAGlobalVariable
function anon () { 
   var thisIsALocalVariable
   thisIsAGlobalVariable = 5; //if you don't use the var prefix inside a fn, it becomes global
}
Bob Gregor
  • 1,163
  • 9
  • 13
  • Ironically, this gotcha seems intuitive to me. – Jeff Davis Aug 04 '10 at 21:04
  • the part that seemed like a gotchya to me was the fact that you can make a variable global inside of a function by omitting the var prefix. Please let me know if I'm mistaken – Bob Gregor Aug 05 '10 at 02:31
0

You are finding it difficult because:

  • javascript has another kind of syntax.
  • javascript is dificult to debug
  • javascript has no autocompletion like c# etc) ?or does it
  • javascript has illogical rules (they become logical once you are known with them)
  • everything can be done in 1000 ways, and when you search for a solution, you will find 2000 answers :) where c#, php mostly have a good practice function u "should/could" use

However, I started using js/jquery a half year ago, with the same reasoning as you do, and I stuck to it, and now I use it daily to enhance my webapps.

I just love it (especcially jquery). It is a life saver, I know what and where to look, I can do about anything with it.

Everything seems logical.

If I can give you one advice: javascript/jquery is a sour apple, but just hang in there, bit trough and you won't regret it.

also, a loooot of people use it and are always willing to lend a hand if needed (I know I do)

Nealv
  • 6,856
  • 8
  • 58
  • 89
  • 1
    IntelliSense (aka "AutoCompletion") is a property of the IDE, not the language. I would strongly challenge your statement that JS is illogical, it's as logical as any language (i.e. it's the programmers fault if it isn't) and the idea that PHP has better implementation path than JS is.. well... just no. – annakata Aug 03 '10 at 16:03
  • IntelliSense is indeed a property, I was refering to the IDE because most languages have great ide support, js less for as far as I know. for the Illogical part, I might have expressed myself wrong, the language is not illogical, but I always have the feeling you have much less restrictions then when using php or C#, they feel more encapsulated in their tiers (but ok javascript actually only has 1 tier). – Nealv Aug 03 '10 at 18:17
0

Javascript is tricky. You don't have a compiler watching your back. To compensate, unit testing becomes more important. I've been doing my unit testing with jQuery/QUnit, but I recently started using Jasmine (http://github.com/pivotal/jasmine) and I recommend it 200%. Its a great testing framework.

If you're not familiar with testing, or testing with javascript, I'd highly recommend finding unit tests for other OSS javascript projects (hopefully for code you could use) and seeing how they test it.

With unit tests, you'll make the same mistakes, but catch them much sooner and with less grief. And if your tests are good, the mistakes won't come back after you fix tham.

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
0

I don't know how much UI design you have done in C, but the event variable only shows up when it is sent by the caller and the handler needs to, well, handle the object. If you do reading on event object, the confusion in q #2 should go away.

There is no event handling in PHP, so I think you have not came across this issue in the past. JavaScript is a programming language with its own purpose, so it was designed to work for that specific purpose.

user58670
  • 1,438
  • 17
  • 17
-1

Maybe you have to link your code to an HTML onclick="event()" button to fire off as the event.

Jamal
  • 763
  • 7
  • 22
  • 32