9 ways to level up your JavaScript code

1. Don’t use commas when declaring variables

Kameron Tanseli
5 min readApr 8, 2017
var a = 2,
b = a + 2,
c = b - 3;
var a = 2;
var b = a + 2;
var c = b - 3;
  • variables can be easily moved around from line to line without having to worry about the commas.

2. Namespace all your code

var fruit = "apple";var fruit = ["apple", "pear"]; // namespace collisionwindow.Basket = window.Basket || {};
Basket.fruit = "apple";
window.Stock = window.Stock || {};
Stock.fruit = "apple";
  • Stops naming collisions

3. Utilize the Module pattern

var Basket = (()=>{
var items = [];
return {
addItem: ()=> {},
removeItem: (index)=> {}
};
})();
  • The closure created by the Immediately Invoked Function Expression (IIFE) allows privacy. E.g: The items array is only accessible through the returned methods.
  • Link to more indepth article

4. Comment your code

/** Class representing a point. */
class Point {
/**
* Create a point.
* @param {number} x - The x value.
* @param {number} y - The y value.
*/
constructor(x, y) {
// ...
}
}
  • Allows developers to get a deeper understanding of what is happening in your code
  • Can be used to generate online documentation guides
  • Industry standard is JSDOC

5. Learn design patterns

  • The Observer pattern helps your modules communicate to each other through events thus providing loose coupling in your app.
  • The Mediator pattern takes control over a group of objects by encapsulating how these objects interact. E.g: a basket that handles items.
  • The Iterator pattern is the underlying pattern for ES2015 generators. Useful to know whats actually going on :D
  • The Facade pattern provides an simple interface which encapsulates the end user from complex functionality. E.g: Email module with simple methods such as start, stop and pause;

Not only are these solutions to commonly solved problems, they are a way of describing application structure to other developers fairly simply. E.g: “The basket module is a mediator for all the store items, it communicates to the payment module via an observer”.

6. Pass objects into functions with a large number of arguments

function colorWidget(element, colorValue, colorRange, colorFormat, opacity, onChange) {

}
colorWidget($("<div/>"), "#fff", ...);function colorWidget(options) {
var config = _.extend({
element: $("<div/>"),
colorValue: "#000",
colorRange: [0, 255],
colorFormat: "rgb",
opacity: 0.8,
onChange: function(){}
}, options);
}
colorWidget({
element: $("<div/>")
});
  • Allows new arguments to be added easily
  • The developer doesn’t have to worry about the order of the arguments
  • Allows the setting of default values easily

This is most commonly seen in the creation of jQuery plugins.

7. Don’t use type constructors unless specifically necessary

var x1 = new Object();
var x2 = new String();
var x3 = new Number();
var x4 = new Boolean();
var x5 = new Array();
var x6 = new RegExp("()");
var x7 = new Function();
var x1 = {};
var x2 = "";
var x3 = 0;
var x4 = false;
var x5 = [];
var x6 = /()/;
var x7 = function(){};
  • Creation through type constructors is significantly slower.
  • Because the end result of the constructor is an Object rather than a primitive value you get nasty side effects like so:
var a = new String("x");
a === "x" //false
a == "x" //true
var b = "dog";
b.woof = true;
b.woof; // undefined
var c = new String("dog");
c.woof = true;
c.woof; // true

8. Make sure your context is right

var Button = {
count: 0,
click: function() {
this.count += 1;
},
init: function() {
$("button").click(this.click);
}
};
Button.init();

From a glance this should work however when a user clicks the button we will get an error that count doesn’t exist. This is because the click function is executed in the context of the $("button") element instead of the Button object. We can fix this by binding the context to the function:

$("button").click(this.click.bind(this));
// or
$("button").click(()=> this.click());

9. Apply

The apply() method calls a function with a given this value and arguments provided as an array (or an array-like object). — MDN

Some useful instances of using apply:

// emulating "super" in an constructor 
SomeConstructor.prototype.somemethod.apply(this, arguments);
// passing an array of promises to jQuery.when
$.when.apply($, [$.get(), $.get()]);
// finding the max number in an array
Math.max.apply(Math.max, [1,2,3,4,5]);

Bonus Points

Contributed by: Russley Shaw

10. Use let and const over var

let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used.

Lets look at a few use cases where this is useful over var statements:

var elements = document.querySelectorAll('p');
for (var i = 0; i < elements.length; i++) {
// have to wrap in IIFE other i would be elements.length
(function(count){
elements[count].addEventListener('click', function(){
elements[count + 1].remove();
});
})(i);
}
// using let
let elements = document.querySelectorAll('p');
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function(){
elements[i + 1].remove();
});
}

The reason why the top example would be elements.length is because i is referenced directly so on the next iteration i is incremented. When we wrap the code in an IIFE we reference i under the parameter count thus removing the direct reference.

const allows the declaration of variables that cannot be re referenced. This is useful for declaring constants (the keyword originates from it).

const API_KEY = '2rh8ruberigub38rt4tu4t4';
const PI = 3.14;

However objects and arrays can still be accessed and changed. To stop this use Object.freeze() :

const API_CONFIG = Object.freeze({
'key': '8ry4iuggi4g38430t5485jmub',
'endpoint': '/some/boring/api/path/'
});
API_CONFIG.key = null; // attempt to change
API_CONFIG.key; //= '8ry4iuggi4g38430t5485jmub'
const EVENS = Object.freeze([ 2, 4, 6, 8]);
EVENS[2] = 9;
EVENS[2]; //= 6

11. Avoid using “or” when referencing variables

The only reason to avoid doing this is when the variable is allowed to be false . Take a look at the example below:

var msg = ''; //= should hide the button
var btnMsg = msg || 'Click Me';
btnMsg; //= 'Click Me'

The reason this happens is due to the conversion of the "” into a Boolean which returns false . As the "” is counted as false the or comparison returns the other side Click Me .

If you want to have shorthand if statements you can use the ternary operator:

var msg = ''; //= should hide the button
var btnMsg = msg.length < 1 ? msg : 'Click Me';
btnMsg; //= ''

If you found this helpful, follow me on Instagram :D

--

--