Monday, August 10, 2015

JavaScript Survival Tools for the Java Developer

Although I've worked with JavaScript a bit here and there over the years, I have not used it as regularly or consistently as I've used Java. I have also not used it for anything nearly as complex as for what I've used Java. Therefore, it is not very surprising that moving from commonly used Java to seldom used JavaScript offers some pain points. This post looks at some tools and techniques Java developers (and developers familiar with other class-based and statically typed languages) might find helpful in transitioning to JavaScript development.

Be Aware / Beware the JavaScript Gotchas: Helpful Online Resources

Every programming language has its share of gotchas, sharp edges, traps, quirks, and corners, but it is difficult for me to think of a programming language (other than perhaps Perl) that has more of these in its fundamental design than JavaScript. The developer who is aware of these is likely still going to run into these occasionally, but awareness will help the developer reduce the number of times he or she falls into the traps.

Given the importance of understanding these JavaScript nuances, the first category of tools is online resources that provide warnings about these nuances and their effects. A good resource providing an overview of JavaScript Gotchas is Seven JavaScript Quirks I Wish I’d Known About. Other resources useful in getting familiar with nuances of JavaScript include Short Guide to JavaScript Gotchas, A Beginner's List of JavaScript Gotchas, and What are the top JavaScript pitfalls?

I have not read the book JavaScript: The Good Parts, but many Java developers who have written about their experiences with JavaScript have mentioned that this book has helped them to better understand how to properly use JavaScript. The recent blog post JavaScript Debugging Tips and Tricks is also very useful in learning about debugging JavaScript.

For me, the biggest (in terms of time spent) issues using JavaScript while using Java is the different handling of scope (and related issues such as hoisting and different meanings of this keyword that take 40 minutes to explain and differ depending on which mode is being used). JavaScript's scope rules are a bit complex (see this StackOverflow thread for a taste of how complex), but boil down for me to essentially "use var often," "embrace functions for controlling scope," and "braces don't mean anything in specifying scope."

See Where You're At with console.log

The ability to log an application's state and a description of an application's behavior is useful in programming and debugging in any programming language. Because JavaScript is a weakly and dynamically typed language, this ability to see what's happening at runtime is even more significant in JavaScript where a compiler is not going to help find "obvious" typos and mismatched interfaces. In the old days, one was typically stuck with invoking alert() to see these types of logging details. This approach lacked subtlety and placed a popup on the screen that the user clicked "OK" on to close. The advent of console.log() is a welcome addition to the JavaScript developer's tool set.

The biggest downside of console.log may be that it's not part of the DOM or JavaScript standards. However, modern major browsers all seem to support it. For those worried about a target environment browser not supporting it, a fall-back to alert can be used. The obvious advantage of console.log is that modern browsers support special windows or areas in the browser in which messages are logged rather than rendering a pop-up that requires user acknowledgement to close. For Java developers familiar with logging using Log4j or java.util.logging, console.log is much closer to what they're used to than alert.

It's also worth mentioning here that non-standard console.dir can be very handy, with its advantages being more obvious in certain browsers than others.

See Where You've Come From with console.trace

The non-standard console.trace is similar to console.log in that it's non-standard but supported by modern web browsers. What makes console.trace different than console.log is that console.trace logs the stack trace of the JavaScript execution at time of the logging invocation. This is similar to logging a thread's current stack trace in Java.

Feel at Home with Constructor Functions

Java developers are comfortable working with objects. Although JavaScript's object-orientation is prototype-based rather than class-based, the use of constructor functions makes JavaScript objects feel more like Java objects. I have discussed the use of constructor functions in greater depth in the post JavaScript Objects from a Java Developer Perspective. The book Object-Oriented JavaScript provides a thorough introduction to using JavaScript objects and I have reviewed this book in an earlier post.

Override JavaScript Objects' toString() Implementations

JavaScript, like Java, provides an implementation of toString() at its highest Object level. All JavaScript objects automatically inherit that toString() implementation via Object.prototype.toString(). Like Java's, the JavaScript Object.toString() provides only minor informative value. The same advantages that come from overriding Java class's toString() implementations apply when overriding JavaScript objects' toString() implementations. Overridden and customized JavaScript objects' toString() methods are especially helpful when used in conjunction with the just-discussed console.log.

I have written about how to override JavaScript objects' toString() methods in the posts JavaScript Objects from a Java Developer Perspective and A Java Developer's Perspective on the Power and Danger of JavaScript's Object Prototype.

Enjoy Java's Write-Once, Run Anywhere Paradigm in JavaScript

Although modern web browsers more consistently implement JavaScript features these days than they used to, there are seemingly countless frameworks available that abstract specifics of browsers' DOMs and other implementation specifics away from the developer. Arguably the most famous and most used of the JavaScript frameworks is jQuery. Most of the Java developers I know who speak positively of JavaScript are developers who use a framework such as jQuery to abstract away their need to worry about DOM and other browser implementation nuances and idiosyncrasies. As I have revisited JavaScript development off and on over the years, I've been impressed with how much the frameworks have improved in recent years compared to the quality and dearth of them several years ago. jQuery was one of the first to really make a difference in JavaScript and several introduced since then have had similarly significant impacts. Java developers understand well the value of being able to write the same code once and have it work on multiple targeted environments.

Another framework that has been popular of late, including among Java developers, is AngularJS.

IDE Familiarity Might Reduce Homesickness

A good IDE can be a valuable tool for anyone wanting to learn the basics of a new programming language. The many "holy wars" over which IDEs and text editors are best provide evidence that many developers prefer IDEs and text editors that they are used to using. Fortunately for Java developments, the dominant Java IDEs (NetBeans, IntelliJ IDEA, Eclipse) provide JavaScript development support.

Play with JavaScript Using Java's Implementation

The Oracle HotSpot JVM provides a JavaScript implementation: Rhino before Java 8 and Nashorn since Java 8.

Play with JavaScript with jsFiddle

If you read many StackOverflow answers tagged as JavaScript, you're likely to see people posting there mentioning that they had tested suggested implementations on jsFiddle. This handy online tool allows developers to "try out" JavaScript to see how it performs without need to set up a browser or other environment.

Check JavaScript with JSLint

For Java developers used to the Java compiler catching all types of minor syntactic issues, JavaScript can sometimes seem too forgiving as it quietly doesn't do what the developer is expecting because of some bad syntax. The online JSLint (The JavaScript Code Quality Tool) is very helpful in identifying JavaScript syntax issues. jslint4java is a Java wrapper for JSLint.

Debugging is Even More Helpful in JavaScript

The ability to debug code is important in any programming language, but it feels even more important in dynamically typed languages such as JavaScript where more errors are pushed to the runtime instead of being encountered earlier during compile time. There are several tools available for helping debug JavaScript applications. These include tools mentioned here such as jsFiddle, but also include browser-specific tools such as the famous and frequently used Firebug and the browers' debugger implementations (Firefox Debugger, Internet Explorer F12 debugger, and Chrome's JavaScript Debugger.

Use a Java-like Abstraction of JavaScript

For the developer who prefers static typing and some of the other advantages of Java and other languages, an approach to more comfortably "writing JavaScript" is to use a superset or abstraction of JavaScript with static characteristics. The idea of compiling from a more statically typed language into JavaScript is not new to Java developers as Google Web Toolkit (GWT) has done this for a long time. A newer implementation of this concept is provided as DukeScript, which is described as a "new technology for creating cross-platform mobile, desktop and web applications" that "are plain Java applications that internally use HTML5 technologies and JavaScript for rendering."

Another option for those wishing to generate JavaScript while using constructs they are familiar with in Java is use of TypeScript, "a typed superset of JavaScript that compiles to plain JavaScript." TypeScript provides stronger typing, classes, interfaces, and other concepts that Java and C# developers are familiar and comfortable with. Many of us who use Java, C++, C#, and languages such as these have learned to love the advantages of strongly typed programming languages and TypeScript presents many of those advantages to us in JavaScript.

Conclusion

JavaScript has become a widely popular and ubiquitous programming language. In several ways, it is quite different from other popular programming languages such as Java and C#. Although experience in any one programming language is generally beneficial in learning a different programming language, there have actually been times that my "thinking in Java" has almost been a detriment when writing JavaScript due to some of the subtle (from a syntax perspective) but drastic (from a behavior perspective) differences in the two languages. This post has outlined some of the tools that I've found helpful for being more effective when developing JavaScript from a primarily Java background.