Promise.spread "Polyfill"
Your implementation is taking .then(a, b) and mapping it to .then(a).catch(b) which is not exactly the same thing.  An exception or return of a rejected promise in a in your implementation will hit the .catch(b), but in .then(a, b), it will not hit b, so I think your .spread() is not correctly imitating the .then() behavior in some circumstances.

Here's my implementation that should more closely mimic .then(a, b):

Promise.prototype.spread = function(a, b) {

    function doSpread(fn) {
        return function(args) {
            if (typeof fn === "function") {
                if (Array.isArray(args)) {
                    return fn.apply(null, args);
                } else {
                    return fn(args);
                }
            } else {
                return args;
            }
        }
    }
    if (typeof b !== "undefined") {
        // there is a reject handler
        return this.then(doSpread(a), doSpread(b));
    } else {
        // no reject handler
        return this.then(doSpread(a));
    }
}

// Array.isArray polyfill
if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}


Working demo and tests: https://jsfiddle.net/jfriend00/nqc0h10y/



And, here's a version that makes the change to wait on any promises that are returned in the array of values per our discussion in comments. I also changed it so that if you don't pass a function to .spread(), it will reject:

Promise.prototype.spread = function(a, b) {

    function doSpread(fn) {
        return function(args) {
            if (typeof fn === "function") {
                if (Array.isArray(args)) {
                    // in cases where there could be promises in the array, wait on those
                    return Promise.all(args).then(function(returnArgs) {
                        // split the array of results into separately passed arguments
                        return fn.apply(null, returnArgs);
                    });
                } else {
                    return fn(args);
                }
            } else {
                throw new Error("Must pass a function to .spread()");
            }
        }
    }
    if (typeof b !== "undefined") {
        // there is a reject handler
        return this.then(doSpread(a), doSpread(b));
    } else {
        // no reject handler
        return this.then(doSpread(a));
    }
}

// Array.isArray polyfill
if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}


Working demo: https://jsfiddle.net/jfriend00/om5auzs0/