Default parameters

by Arnaud Buchholz

CSS

.ok {
  color: green;
}

.ko {
  color: red;
}

JavaScript

function test(label, result, expected) {
    var line = document.createElement("div");
    line.appendChild(document.createTextNode(label + ": "));
    var span = document.createElement("span");
    span.className = (result === expected || isNaN(expected) && isNaN(result)) ? "ok" : "ko";
    span.appendChild(document.createTextNode(result));
    span = line.appendChild(span);
    return document.body.appendChild(line);
}

Function.prototype.withDefaults = function () {
    var defaultParameters = [].slice.call(arguments),
        wrappedFunction = this;
    return function () {
        var receivedParameters = [].slice.call(arguments),
            missingCount = wrappedFunction.length - receivedParameters.length,
            actualParameters,
            sliceFrom;
        if (missingCount > 0) {
            sliceFrom = defaultParameters.length - missingCount;
            actualParameters = receivedParameters
                .concat(
                    new Array(Math.max(-sliceFrom, 0)),
                    defaultParameters.slice(Math.max(sliceFrom, 0))
                );
        } else {
            actualParameters = receivedParameters;
        }
        return wrappedFunction.apply(this, actualParameters);
    }
}

function add(value, increment) {
    return value + increment;
}

var inc = add.withDefaults(1),
    one = add.withDefaults(0, 1);

test("Returns a function", typeof inc, "function");
test("inc(1)", inc(1), 2);
test("inc(1, 2)", inc(1, 2), 3);
test("inc()", inc(), Math.NaN); // will lead to undefined + 1
test("one()", one(), 1);
test("one(1)", one(1), 2);
test("one(1, 2)", one(1, 2), 3);