The other answers already did point to the source of the OP's code malfunction. Writing more descriptive code, the problem literally boils down to an "array-detection/-reduce/-concat-recursion" ...
(function (Array, Object) {
//"use strict";
  var
    array_prototype       = Array.prototype,
    array_prototype_slice = array_prototype.slice,
    expose_internal_class = Object.prototype.toString,
    isArguments = function (type) {
      return !!type && (/^\[object\s+Arguments\]$/).test(expose_internal_class.call(type));
    },
    isArray     = function (type) {
      return !!type && (/^\[object\s+Array\]$/).test(expose_internal_class.call(type));
    },
    array_from  = ((typeof Array.from == "function") && Array.from) || function (listAlike) {
      return array_prototype_slice.call(listAlike);
    },
    array_flatten = function flatten (list) {
      list = (isArguments(list) && array_from(list)) || list;
      if (isArray(list)) {
        list = list.reduce(function (collector, elm) {
          return collector.concat(flatten(elm));
        }, []);
      }
      return list;
    }
  ;
  array_prototype.flatten = function () {
    return array_flatten(this);
  };
}(Array, Object));
borrowing code from one of the other answers as proof of concept ...
console.log([
  [[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]],
  [[[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]]]
].flatten());
//[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, ..., ..., ..., 0, 1, 2]