Voici une solution récursive simple et non fantaisiste :
function cartesianProduct(a) { // a = array of array
var i, j, l, m, a1, o = [];
if (!a || a.length == 0) return a;
a1 = a.splice(0, 1)[0]; // the first array of a
a = cartesianProduct(a);
for (i = 0, l = a1.length; i < l; i++) {
if (a && a.length)
for (j = 0, m = a.length; j < m; j++)
o.push([a1[i]].concat(a[j]));
else
o.push([a1[i]]);
}
return o;
}
console.log(cartesianProduct([[1, 2], [10, 20], [100, 200, 300]]));
// [
// [1,10,100],[1,10,200],[1,10,300],
// [1,20,100],[1,20,200],[1,20,300],
// [2,10,100],[2,10,200],[2,10,300],
// [2,20,100],[2,20,200],[2,20,300]
// ]