Облегченный модуль JavaScript для необязательных параметров / параметров по умолчанию - PullRequest
0 голосов
/ 10 февраля 2012

Существует ли модуль JavaScript, который позволяет легко сопоставлять аргументы с параметрами?Вот как я представляю, как это работает:

var arguments = assignArguments (arguments, 'p1', 'p2', [{'p3': 0}, 'p4'], {'p5': 'unknown'});

Внутри функции вы вызываете ее для создания объекта, который связывает параметр с аргументом.Параметры, определенные в массиве или встроенном объекте, будут считаться необязательными, тогда как встроенные объекты позволят назначать значения по умолчанию.Все остальные параметры считаются «обязательными».

Вот несколько примеров ввода / вывода:

foo(1): { p1: 1, p3: 0, p5: 'unknown' } // no p2 (aka undefined) 
foo(1, 2): { p1: 1, p2: 2, p3: 0, p5: 'unknown' } 
foo(1, 2, 3): { p1: 1, p2: 2, p3: 0, p4: 3, p5: 'unknown' } 
foo(1, 2, 3, 4): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 'unknown' } 
foo(1, 2, 3, 4, 5): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 5 }

Я надеюсь, что подобная библиотека уже существует.Эта логика часто повторяется, и я хочу устранить ее, если это возможно.

Кто-нибудь знает о такой библиотеке?Если нет, может кто-нибудь прислать мне правильный путь для его реализации?

1 Ответ

0 голосов
/ 13 февраля 2012

Я пошел вперед и подумал о способе сделать это сам. Он включает в себя анализ графа объектов, состоящего из строк, массивов и объектов. Это довольно долго, но работает хорошо.

function assignArguments(values, expression) {              
    // determine how many arguments are needed for each parameter
    // grab all of the defaults, too
    var needed = 1;
    var argsNeeded = {};
    var defaults = {};
    var queue = [expression];               
    for (var queueIndex = 0; queueIndex < queue.length; ++queueIndex) {
        var node = queue[queueIndex];
        if (typeof node === 'string') {
            // the node is a required parameter
            argsNeeded[node] = needed;
            ++needed;
        } else if (node instanceof Array) {
            // the node is a list of parameters
            for (var index = 0; index !== node.length; ++index) {
                queue.push(node[index]);
            }
        } else {
            // the node is a list of optional parameters with defaults
            // make sure there isn't more than one parameter
            var count = 0;
            for (var key in node) {
                if (node.hasOwnProperty(key)) {
                    if (count !== 0) {
                        throw new Error('A default parameter list had more than one value.');
                    }
                    defaults[key] = node[key];
                    queue.push(key);
                    ++count;
                }
            }
        }
    }

    // determine the order that the parameters appear
    var parameters = [];
    var stack = [expression];
    while (stack.length > 0) {
        var node = stack.pop();
        if (typeof node === 'string') {
            // the node is a required parameter
            parameters.push(node);
        } else if (node instanceof Array) {
            // the node is a list of parameters
            var index = node.length;
            while (index !== 0) {
                --index;
                stack.push(node[index]);
            }
        } else {
            // the node is an optional parameter with defaults
            // we'll check for multiple parameters
            var count = 0;
            for (var key in node) {
                if (node.hasOwnProperty(key)) {
                    if (count > 0) {
                        throw new Error('A default parameter list had more than one value.');
                    }
                    stack.push(key);
                    ++count;
                }
            }
        }
    }

    var result = {};
    var valueIndex = 0;
    for (var index = 0; index !== parameters.length; ++index) {
        var parameter = parameters[index];
        var needed = argsNeeded[parameter];
        if (needed > values.length) {
            if (parameter in defaults) {
                result[parameter] = defaults[parameter];
            }
        } else {
            result[parameter] = values[valueIndex];
            ++valueIndex;
        }
    }

    return result;
}

А вот пример использования его.

function foo() {
    var params = assignArguments(arguments, ['p1', 'p2', [{p3:0}, 'p4'], {p5: 'unknown'}]);
    return params;
}

console.log(foo(1));
console.log(foo(1, 2));
console.log(foo(1, 2, 3));
console.log(foo(1, 2, 3, 4));
console.log(foo(1, 2, 3, 4, 5));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...