Thursday, 25 April 2013

Is JavaScript Really So Bad?

I’ve had some pretty strong opinions on JavaScript in the past, most of them negative as a previous post has explained. Having been forced into using it more fully recently on several mini-projects though my rigid opinions on it have softened slightly.

Despite working on web technologies I don’t really consider myself a web developer; I am most comfortable in working on server-side code, usually in C#. So when the time comes when I am faced with HTML, CSS and JavaScript I do tend to get a little overwhelmed; I can be extremely productive in C# but tying server-side code to a front-end interface can take me hours, more likely days, to get an end result that I’m not even that happy with. It is this mindset I think that clouds my judgement with JavaScript; I’m simply not that proficient in using it and don’t continue developing this skillset to allow me to improve.

Part of the problem I think is that I am most familiar with ASP.NET WebForms. When I first started web development proper I worked on WebForms and was able to bypass a lot of issues around learning good HTML/CSS/JavaScript practices because WebForms managed most of the functionality for you; just tie up server controls, set some properties and the final rendered result would somehow magically do what you wanted it to. I still work in WebForms but now I’m trying to get more involved with ASP.NET MVC, both in a professional and recreational sense, but there’s a problem; MVC is an excellent framework but it does less for you than WebForms. You have full control over the HTML you output but now I need to know the finer details that WebForms so successfully hid from me all these years, including even simple things like what happens when a HTML form sends a POST request back to the server.

So given that I’ve been working a bit more on MVC websites recently in various capacities I took the opportunity to try and “reset” my thinking process and try and work with JavaScript as it was intended and not as an afterthought or constant hindrance. Over the past few weeks I’ve now started to form these opinions instead:

Separation of Concerns

Below is a typical example of the kind of webpage I’m most used to seeing:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My webpage</title>
<style type="text/css">
.banner
{
background-color
: red;
}
</style>
<script type="text/javascript">
function firstLoad() {
alert(
"Hello World!");
}
</script>
</head>
<body onload="firstLoad()">
<div class="banner">
Welcome!
</div>
<a href="Next.html" style="padding: 10px" onclick="javascript: alert('You clicked me!')">Next page</a>
</body>

Yuck! See how it mixes HTML, CSS and JavaScript into one file? Unfortunately this is what I see a lot of and, I’m ashamed to say, even do myself because it is easy to do. But then I’ll run into problems like how to test or debug that JavaScript. Take the example of the hardcoded onclick handler on that anchor tag; it’s a simple example but what if it was something more complicated? How could I test that when I find it doesn’t work like I expected?


So instead I’ve tried to decouple the parts of the webpage into a file each for HTML, CSS and JavaScript as nearly every web developer recommends. From this I’ve found it is now easier to edit and view my work; if I want to change the style of an element I go to my CSS file and not hunt for it in the monolithic file and similarly if I need to make a code change I update the script file and reload.


jQuery


OK, now I’ve got my code separated from everything else so now I can just focus on the functionality of the page, but how do I do <insert cool fancy feature here>? On it’s own JavaScript doesn’t provide a lot for you. Sure, I can use getElementById() to find various parts of the page but after that do I then write a huge amount of code to do a relatively simple thing? No, I would use one of the bazillion JavaScript frameworks out there. To my mind jQuery is the top framework that everyone thinks of.


I spent about a week of playing around with jQuery and using selectors and effects to manipulate the page, calling back to the server to process some JSON data and so on. As a newbie I did have to search around on the internet quite a bit to figure out how to do some simple things but the advantage of jQuery is that, because it is so prolific, there are tons of resources and samples out there to use.


All in all I now can’t imagine trying to do anything in JavaScript now without using jQuery as it just makes things so much simpler.


JavaScript IntelliSense


I will freely admit that I completely rely on IntelliSense when writing .NET code. Why bother memorising thousands of APIs when a simple list can show you what is available? IntelliSense works brilliantly for statically typed languages but JavaScript is a dynamic language; at any point during execution the floor could potentially be pulled up beneath you and the API you thought was available could be changed. The dynamic nature of JavaScript is definitely a positive in a lot of cases but not when it comes to trying to discover what APIs are available, going back to relying on *shudder* reading documentation.


As it turns out though Visual Studio now has a way of trying to provide IntelliSense some information when writing JavaScript code by including reference comments in your file. These seem to work a little like import statements or C-style #include instructions but instead of pulling in code dependencies it looks for source code commenting and adds that information to IntelliSense. I tried it on jQuery and suddenly I can see everything that jQuery is capable of. Amazing!


Having this in JavaScript is such a big time saver for me because:



  1. It saves round-trips to reading documentation and determining what each function is and what it requires. A simple tooltip which shows what parameters are needed and what they do is a great help to me.
  2. It helps a lot in discovering the APIs. jQuery as an example has lots of functions available but how many? And what do they do? Sometimes just having a simple list of functions available is enough to make you wonder what one does and could end up helping you figure out your solution.

Function Callbacks


And now onto some minor gripes I still have with JavaScript!


One of the little annoyances I’m coming across, especially with jQuery’s constant need of function parameters, is that the syntax for creating a nameless function (or sometimes referred to as a lambda function in other languages) is particularly verbose. Here is what I mean:


$(document).ready(function () {
$(
".tag").each(function (index, element) {
// Do something here
});
});

Having to write the word function gets a bit tiring when doing it over and over again – especially as JavaScript can be minified, you would think that you would want something shorter to use. Whereas in C# using LINQ I could write something like this:


var results = list.Where(x => x.Age > 10).Select(x => x.Name);

Notice how this “fat arrow” syntax makes things more concise. It does appear though that this is being included in the ES 6 specification so hopefully I will see this in JavaScript one day, I just wish it was now!


But It’s Still Not Working…


By biggest bug-bear with JavaScript though is still the fact that I can write lots of lovely code and it may still not work and the browser won’t tell me it doesn’t work! Rather than tell me anything useful it will simply ignore anything that won’t work and just silently carry on, leaving me bewildered as to why what I expect to happen doesn’t.


Here is a typical conversation I end up having with my computer:


Me: OK, let’s run this and check my new feature works.


Computer:


Me: Er, hello? Did you do anything? Nothing has happened.


Computer: Sorry, I can’t find that new function you wrote.


Me: But it’s in my source file right here!


Computer: Well it’s not in my cached version which didn’t update on the last page load.


Me: Oh right, the browser cache. *sigh* Let me clear it and reload.


Computer: Ah, now I see your new function!


Me: Great, but still nothing is happening.


Computer: Well no, I can’t find an element with an ID called “banner”.


Me: Er, that’s meant to be “Banner”. With an uppercase “B”.


Computer: Well if you can’t spell that’s your own fault. *snigger*


Me: *grumble* Fine… *fixes spelling* There, happy now?


Computer: No, now I can’t find your new function. Have you tried clearing your browser cache?


Me: *bangs head on table*


…and so on.


Unfortunately this feedback loop happens all the time with me. Perhaps it will improve with experience but at the moment I do end up getting frustrated that no useful developer information is conveyed to me when something goes wrong.



Conclusion


Overall though I am starting to find JavaScript more useful now. When it is coupled with a powerful framework to assist you and you accept it for what it is and not try and compare it to another language I realise now that you can achieve quite a lot with it. Which is useful as it seems that we’ll all be using JavaScript for a long time to come.

No comments:

Post a Comment