Preventing Side Effects in JavaScript
JavaScript is very dynamic these days but I still see a lot of legacy code, whether it be for optimal backward compatibility or simply that the code hasn't been maintained. One of the practices that makes me cringe is coding that creates unwanted side effects. What's a side effect? A piece of code whereby a variable is created and available throughout a scope when it doesn't need to be. Let me show you a few examples and how to avoid these unwanted side effects.
Array.prototype.forEach()
instead of for(var x = ...)
Looping through a JavaScript array was traditionally done via a for()
loop:
var myArray = [1, 2, 3]; for(var x=0, length = myArray.length; x < length; x++) { // ... } // "x" and "length" are side effects
The side effect of this pattern is at minimum the running index, if not the length as well -- they are available within the entire scope. Array
prototype methods like map
, forEach
, and every
allow the developer to avoid these side effects:
[1, 2, 3].forEach(function(item, index, array) { // No side effects! :) });
No "utility" variables need to be created for the looping, thus avoiding side effects. This is called "functional" programming.
Self-Executing Functions
If you haven't read Hiding Your Privates with JavaScript, and you don't know how to keep private variables in JavaScript, take a few minutes to read it. The same pattern provided in that post allows you to avoid side effects via self-executing functions:
// Example from MooTools source... Browser.Request = (function(){ var XMLHTTP = function(){ return new XMLHttpRequest(); }; var MSXML2 = function(){ return new ActiveXObject('MSXML2.XMLHTTP'); }; var MSXML = function(){ return new ActiveXObject('Microsoft.XMLHTTP'); }; return Function.attempt(function(){ XMLHTTP(); return XMLHTTP; }, function(){ MSXML2(); return MSXML2; }, function(){ MSXML(); return MSXML; }); })(); // The three vars are stuck in the self-executing function, they don't "leak" out
The gist is that you can do loads of processing within the self-executing function (a new scope) without allowing variables leaking out -- the only item returned or leaked is the desired return value.
Tightening up your code includes avoiding side effects and JavaScript makes it easy if you follow these basic practices!
This is a good start, but the philosophy of side-effect free programming runs much deeper, and forms the foundation of the functional programming paradigm. To help people understand the philosophical underpinnings, I wrote “The Dao of Immutability”: https://medium.com/javascript-scene/the-dao-of-immutability-9f91a70c88cd
Very informative article, david. I have touched up the unfinished
forEach
function for the reader to continue reading http://gadgets-code.com/javascript-array-prototype-foreach-method-usage