9 ways to level up your JavaScript code

April 08, 2017 0 Comments

9 ways to level up your JavaScript code

 

 

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.
var fruit = "apple";
var fruit = ["apple", "pear"]; // namespace collision
window.Basket = window.Basket || {};
Basket.fruit = "apple";
window.Stock = window.Stock || {};
Stock.fruit = "apple";
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
/* 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
  • 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”.

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.

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
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());
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]);

Contributed by: Russley Shaw

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 APIKEY = '2rh8ruberigub38rt4tu4t4';
const PI = 3.14;

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

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

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; //= ''


Tag cloud