SHARE
Facebook X Pinterest WhatsApp

Three JavaScript Anti-Patterns and How To Avoid Them

Dec 21, 2012

In programming, a pattern represents a best practice, while an anti-pattern represents a lesson that has been learned. The term anti-patterns was coined in 1995 by Andrew Koenig in the November C++ Report that year, inspired by the Gang of Four‘s book Design Patterns. In his report, Koenig describes anti-patterns as a bad solution to a particular problem which resulted in a bad situation occurring, which provide some degree of guidance on how to get out of said situation and get to a satisfactory solution. In today’s article, we’ll be taking a look at three of the biggest anti-patterns in JavaScript as well as their solutions.

Extending Object

Perhaps the most frowned-upon anti-pattern is the extending of the base Object’s prototype. This is considered to be very bad practice mainly because it breaks for in loops. Consider the following:

var obj = {a: "A", b: "B", c: "C", d: "D"};
for (var key in obj) {
   alert(key +': '+obj[key]); //displays "a: A", "b: B", "c: C", "d: D"
}

Object.prototype.e = "E";
for (var key in obj) {
   alert(key +': '+obj[key]); //displays "a: A", "b: B", "c: C", "d: D", "e: E"
}

var obj2 = {a2: "A2", b2: "B2", c2: "C2", d2: "D2"}; 
for (var key in obj2) {
   alert(key +': '+obj2[key]); //displays "a2: A2", "b2: B2", "2c: C2", "d2: D2", "e: E"
}

The e property is now inherited by all objects, whether you want it or not.

The preferred way to add shared object attributes is to create your object first and extend it. I wrote about the Object.create() method just a short time ago. It’s supported in all of the newest browsers including IE 9. For compatibility with older browsers, we can supply our own as follows:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

Here’s a base Person class that we will extend from later to make subclasses:

function Person(name, sex) {  
  Person.prototype.populationCount++;  
  Person.prototype.getName=function(){ return name };  
  Person.prototype.getSex=function(){ return sex };  
  Person.prototype.setSex=function(newSex){ sex = newSex; };  
  Person.prototype.die=function(){ Person.prototype.populationCount -- ; };
}
Person.prototype.populationCount=0;

var rob = new Person('Rob','male');
var jeanie = new Person('Jeanie','female');
alert(rob.populationCount);  // displays 2

//the following creates a new public property for rob and sets it to 12
rob.populationCount+=10;
alert(rob.populationCount); //displays 12
alert(jeanie.populationCount); //still displays 2

Child.prototype = Object.create(Person.prototype);
Child.prototype.constructor = function Child(name, sex, age) {
    //call the parent constructor
    Person(name, sex);
    Child.prototype.getAge = function() { return age; };
}
var child = new Child('Ralph', 'male', 3);

alert(child.getName()); //displays "Ralph"
alert(child.getAge());  //displays 3

Pollution of the Global Namespace

AC/DC once proclaimed that Rock & Roll ain’t noise pollution. Improperly declared variables are a whole other ball game. Polluting the Global namespace makes it much likelier that variables will clash and unwittingly set them to the wrong values. In JavaScript, which lives in a browser sand box, the global namespace is the window object. You don’t have to declare a variable using the var keyword; as soon as you start to use it, and the variable hasn’t already been defined, it is simply appended to the global namespace. Hence, x = 2; and window.x = 2; are equivalent. Look at what can happen when you define a c counter in a for loop without the var keyword:

function myFunc() { 
  for (c=0; c

Besides always including the var keyword when declaring your variables, another good idea is to include the ECMAScript 5 “use strict” statement at the top of your scripts. While not yet supported by all of the major browsers, it doesn’t cost anything to start using it right away.

You can also place it within a function to turn on strict mode only within its limited scope:

function strictFunc(){
  "use strict";
  // code ...
}

You should also minimize the use of global variables – that is those outside of objects or functions – and global functions. At the very least, you should give your global variables names that clearly identify them as your own. Short names using special characters like “$” and “@” are very likely to clash with those of JS libraries.

Create your own namespaces to group common functionality. That will protect a whole group of variables:

var Finance = {};
Finance.INTEREST_RATE = 2.5;
Finance.calcAnnualizedInterest(startVal, endVal) {
  //...
}

Improper Use of Truthy and Falsey Evaluation

JavaScript incorporates the concept of truthy and falsey values. This allows expressions that do not explicitly return true or false can be coerced into a boolean value for evaluation. That process is called implied typecasting. Developers who don’t fully grasp the implications of truthy and falsey evaluation tend to perform overblown filtering in their if and loop tests. Take a look at the following statement:

if (testString != undefined && testString != '') {
  //do something
}

It can be safely reduced to:

if (!testString) {
  //do something
}

Values of zero (0), an empty string (“”), null, undefined, and NaN are all falsey in JavaScript. Hence the following loop will not execute:

var testval; //this is undefined
while (testval) {
  //do something
}

To avoid confusion caused by implied typecasting always use the === and !== identity operators to check both the values and the type of the expressions you are comparing:

var zero = 0;
if (zero === false) {
  // doesn't execute because zero is 0, not false
}

Conclusion

It’s important to not just be knowledgable about best practices, but to also be aware of their alter-ego, the anti-pattern. By doing so, you’ll avoid a lot of the common issues that plague inexperienced developers.

Recommended for you...

The Revolutionary ES6 Rest and Spread Operators
Rob Gravelle
Aug 23, 2022
Ahead of Time (AOT) Compilation in Angular
Tariq Siddiqui
Aug 16, 2022
Converting a JavaScript Object to a String
Rob Gravelle
Aug 14, 2022
Understanding Primitive Type Coercion in JavaScript
Rob Gravelle
Jul 28, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.