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.
- 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.
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.
Problem: Unnecessary extension of Object.prototype.
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.
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: 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!