Lessons Learned from Reviewing JavaScript Code


Recently, I had the opportunity to review a JavaScript code for a new application. The feedback I provided covers some key JavaScript fundamentals that are always worth keeping in mind. Code reviews can greatly improve the overall quality of your solutions. If you haven’t been taking advantage of them, you might be missing out on identifying bugs or receiving suggestions for enhancing your code.

Challenges and Solutions:

Code reviews play a crucial role in maintaining strong coding standards. However, they don’t always prevent logical errors or misunderstandings about the intricacies of a programming language. Even experienced developers can make these types of mistakes, and code reviews can help catch them.

The most challenging part of code reviews is finding an experienced developer whom you trust to complete the review. Additionally, learning to accept and benefit from criticism of your code can be daunting.

When faced with criticism, our immediate reaction is often to defend ourselves or our code. However, it’s important to view criticism as an opportunity to learn and improve. It’s worth remembering that nobody is obligated to provide feedback on your work. If someone takes the time to offer constructive feedback, regardless of whether you choose to implement it or not, you should appreciate their efforts.

See also  JavaScript Projects For Your Portfolio

Options for JavaScript Code Reviews:

If you’re a JavaScript developer looking for code reviews, there are a few different options available:

  • JSMentors: This mailing list is dedicated to JavaScript discussions and offers experienced developers who can provide constructive feedback on code submissions.
  • Code Review Beta: Similar to StackOverflow, this platform allows you to request peer reviews of your code. It’s a useful tool for receiving subjective feedback on improving the quality of your code.
  • Twitter: Surprisingly, social networks can be a valuable resource for code reviews, especially if your code is open-source. Interacting with experienced developers on platforms like Twitter can lead to constructive feedback. Just make sure to engage with developers who have sufficient experience in code reviews.

My Review:

Now, let’s dive into the review itself. A reader asked me to go through their code and suggest improvements. Although code reviews aren’t my area of expertise, I believe they should point out flaws in the implementation while also offering potential solutions and suggestions for further reading.

Here are the problems and solutions I proposed for the reader’s code:

Problem: Inadequate validation for functions used as callbacks.

Feedback: When passing functions as parameters, it’s essential to test their existence and check their type to avoid potential errors.

For a more detailed explanation of typeof operator issues beyond function validation, refer to Angus Croll’s insightful article here. Keep in mind that typeof null returns “object,” which is incorrect. It’s recommended to use Object.prototype.toString to accurately determine an object’s type.

Problem: Repetitive checks for app-specific conditions throughout the codebase.

Feedback: Consider implementing the load-time configuration pattern, which involves testing a condition only once during application load and accessing the test result for future checks. This pattern optimizes JavaScript libraries for specific browsers and can eliminate repetitive checks.

See also  Function Practice in Javascript

For a practical example of load-time configuration pattern, refer to Stoyan Stefanov’s book ‘JavaScript Patterns.’

Problem: Unnecessary extension of Object.prototype.

Feedback: It is generally ill-advised to extend native objects like Object.prototype, as it can cause naming collisions and break object-as-hash tables in JavaScript. While there might be exceptional cases where extending Object.prototype is necessary, it should be a last resort and well-documented within the team.

For a detailed discussion on extending built-in native objects, refer to this informative post by @kangax: Extending Built-in Native Objects: Evil or Not?

Problem: Excessive blocking of the page due to waiting for processes or data.

Feedback: To avoid blocking the page, consider using Deferred execution techniques, such as promises and futures. Instead of issuing blocking calls, return a promise for a future value that will eventually be fulfilled. This allows you to write non-blocking logic that can run asynchronously.

For a comprehensive guide on Deferred execution using jQuery, check out this post by Julian Aubourg: Using Promises and Futures. If you prefer a more basic implementation, Douglas Crockford’s promises can be found here.

Problem: Using the == operator for explicit numeric equality.

Feedback: Consider using the === operator for more specific type comparison. The == operator performs type conversions, which can lead to unexpected results. By using ===, you ensure strict comparison without conversion.

If you want to understand the intricacies of the == operator, @kangax offers valuable insights in this post.

Problem: Unoptimized array.length usage in for loops, particularly with ‘HTMLCollection’s.

Feedback: Avoid repeatedly accessing array.length within loops, as it can significantly impact performance, especially when working with ‘HTMLCollections.’ By caching the array length, you can improve performance by a substantial margin.

See also  Best Websites for Learning JavaScript for Free

For a comparison of performance benefits between cached and uncached array lengths, refer to this jsPerf test.

Problem: Variables declared in various places.

Feedback: To improve code readability and prevent logical errors caused by hoisting, use the single-var pattern. Declare all variables at the top of the function’s scope.

Also, consider initializing variables with a value to minimize logical errors, as uninitialized variables are set to undefined by default.

Problem: Inconsistent usage of $.each() and standard JavaScript loops.

Feedback: Although $.each() has its benefits, standard JavaScript loops like ‘for’ and ‘while’ perform better, especially when dealing with potentially large quantities of data. Given the data-centric nature of the application, consider refactoring your code to use standard loops.

Problem: Dispersed configuration settings.

Feedback: Instead of storing configuration settings in separate variable declarations, consider using the configuration object pattern. This approach improves readability, maintainability, and extensibility, although it might result in non-minified property names.

Problem: Inefficient construction of JSON strings using string concatenation.

Feedback: Optimize the construction of JSON strings by using the JSON.stringify() method. This method simplifies the process and results in shorter, more concise code.

Problem: Invalid namespacing pattern.

Feedback: While the rest of the application implements namespacing correctly, the initial check for namespace existence is invalid. A more effective pattern involves a boolean conversion with an inner variable declaration.

For an extensive exploration of namespacing patterns, refer to @kangax’s detailed post.

That’s it! If you found this code review helpful, I might consider posting more in the future. Good luck with your own projects and reviews!