Introduction
Memoization is a technique used to cache result of a previously calculated value thus can avoid the need to recalculate.
Simplest example.
function square(num){
return num*num;
}
square(10) //100
Each time when we call square(), value will re-calculate. Caching result is importent when we do CPU intensive tasks.
Re-writing above code using cache
Method 1
function square(num){
var result = '';
if(!square.cache[num]){
console.log("Computing value...");
result = num*num;
square.cache[num] = result;
}
return square.cache[num];
}
square.cache = {}
square(10) //First time when we call this function. It calculates the value & cache it.
square(10) // Second time onwards it return the result from cache.
square(20) // square function will calculate again if its a new value.

Method 2 Using hasOwnProperty
This method is useful when there are multiple arguments.
var square = function(num){
var key = Array.prototype.slice.call(num).join("");
// This won’t work if argument send as Object. Eg:- newFun({name:”my name”, age:20});
if(!square.cache[key]){
var result={};
result = num *num;
//Computation
console.log("Computing value...");
square.cache[key] = result;
}
return square.cache[key];
}
square.cache = {};
Method 3 Using JSON.stringify, Array.join or argument.callee.
This method is useful when there are multiple arguments.
var square = function(num){
var key = Array.prototype.slice.call(num).join("");
// This won’t work if argument send as Object. Eg:- newFun({name:”my name”, age:20});
if(!square.cache[key]){
var result={};
result = num *num;
//Computation
console.log("Computing value...");
square.cache[key] = result;
}
return square.cache[key];
}
square.cache = {};
—-or—-
var square = function(num){
var key = JSON.stringify(Array.prototype.slice.call(num));
if(!square.cache[key]){
var result={};
//Computation
console.log("Computing value...");
result = num*num;
square.cache[key] = result;
}
return square.cache[key];
}
square.cache = {};
—or—-
var square = function(num){
var thisFunc = arguments.callee, result;
if(!thisFunc.cache[num]){
result = {}
//Computation
console.log("Computing value...");
result = num*num;
thisFunc.cache[num] = result;
}
return thisFunc.cache[num];
}
square.cache = {}
Above method is not recommended since arguments.callee should be avoid and ECMAScript forbids use of arguments.callee() in strict mode.
Method 4
This will create a higher-order function called memoize() that accepts function and return a memoized version of it.
function memoize(f){
var cache = {};
return function(){
var key = JSON.stringify(Array.prototype.slice.call(arguments));
if(key in cache){
console.log('From cache...')
return cache[key]
}else{
console.log('Computing..')
return cache[key] = f.apply(this,arguments);
}
}
}
//Usage
var squareMem = memoize(square)
squareMem(10);//100

—Or—
Function.prototype.memoiz = function(){
var cache = {}, self = this;
return function(arg){
var key = JSON.stringify(Array.prototype.slice.call(arguments));
if(key in cache){
console.log('From cache...')
return cache[key]
}else{
console.log('Computing..')
return cache[key] = self(arg);
}
}
}
//Usage
var squareMem = square.memoiz()
squareMem(10);
squareMem(20);
squareMem(30);
squareMem(40);
squareMem(50);

Under Closure section you can find all the cached results

memoiz.js is a memoization library hosted in Github.
References Faster javascript memoization Speed up your JavaScript, Part 3 A Better Javascript Memoizer