Armour
A micro-module to prevent side-effects.
(Utilizes deep-copy)
why?
Side-Effects are evil. Protect your functions from the bane of side-effects with armour
, the paladin of JS functions.
what's a side-effect?
Quoting wikipedia: "In computer science, a function or expression is said to have a side effect if, in addition to returning a value, it also modifies some state or has an observable interaction with calling functions or the outside world."
hey! JS is pass-by-value
Yes, but JS does pass-by-value of a reference for non-primitive types, hence why - while JS technically is not a pass-by-reference language - the result is the same as a pass-by-reference...
Utimately, all that matters is that if you do:
var o = { name: 'joe'};
function change(obj) {
o.name = 'changed';
}
change(o);
your o
object is busted.
JavaScript is susceptible to side-effects because it is possible to modify variables outside of a function's scope (something that is very useful when using closures, if you know what you're doing), and because of call-by-value/sharing/mood behaviour.
For example, your junior developer has developed this beauty:
function mul(arr, val) {
var i = 0,
len = arr.length;
for (i; i < len; i += 1) {
arr[i] = arr[i] * val;
}
return arr;
}
after appropriate corporal punishment of the developer in question, you decide to prevent the original array from being ruined by inexperienced/ insane / sado-masochist developers.
Usage
var armour = require('armour');
var safeMul = armour.protect(mul);
now if you have an array var a = [1, 2, 3];
and pass it into mul
:
var b = mul(a, 3);
var c = safeMul(b, 3);
You can also protect an entire object with protectObject
: this means you can pass an object and if any of its properties are functions, they will be protected so they don't cause side effects:
var o = { mul: mul };
var protected = armour.protectObject(o);