Операторы Splat в JavaScript, эквивалентные * args и ** kwargs в Python?

Я использую Python много, и я просто быстро изучаю JavaScript прямо сейчас (или я должен повторить обучение). Итак, я хотел спросить, что эквивалентно *args и **kwargs в JavaScript?

Ответ 1

Ближайшая идиома для *args будет

function func (a, b /*, *args*/) {
    var star_args = Array.prototype.slice.call (arguments, func.length);
    /* now star_args[0] is the first undeclared argument */
}

используя тот факт, что Function.length - это число аргументов, приведенных в определении функции.

Вы можете упаковать это в небольшую вспомогательную процедуру, например,

function get_star_args (func, args) {
    return Array.prototype.slice.call (args, func.length);
}

а затем сделать

function func (a, b /*, *args*/) {
    var star_args = get_star_args (func, arguments);
    /* now star_args[0] is the first undeclared argument */
}

Если вы настроены на синтаксический сахар, напишите функцию, которая преобразует одну функцию в другую, которая вызывается с обязательными и необязательными аргументами и передает требуемые аргументы вместе с любыми дополнительными необязательными аргументами в виде массива в final позиция:

function argsify(fn){
    return function(){
        var args_in   = Array.prototype.slice.call (arguments); //args called with
        var required  = args_in.slice (0,fn.length-1);     //take first n   
        var optional  = args_in.slice (fn.length-1);       //take remaining optional
        var args_out  = required;                          //args to call with
        args_out.push (optional);                          //with optionals as array
        return fn.apply (0, args_out);
    };
}

Используйте это следующим образом:

// original function
function myfunc (a, b, star_args) {
     console.log (a, b, star_args[0]); // will display 1, 2, 3
}

// argsify it
var argsified_myfunc = argsify (myfunc);

// call argsified function
argsified_myfunc (1, 2, 3);

С другой стороны, вы можете просто пропустить весь этот бесполезный слон, если вы хотите попросить вызывающую сторону передать необязательные аргументы в виде массива для начала:

myfunc (1, 2, [3]);

На самом деле аналогичного решения для **kwargs не существует, поскольку у JS нет аргументов с ключевыми словами. Вместо этого просто попросите вызывающую сторону передать необязательные аргументы в качестве объекта:

function myfunc (a, b, starstar_kwargs) {
    console.log (a, b, starstar_kwargs.x);
}

myfunc (1, 2, {x:3});

Обновление ES6

Для полноты позвольте мне добавить, что ES6 решает эту проблему с помощью параметра rest. Смотрите Javascript - & # 39;... & # 39; смысл

Ответ 2

ES6 добавил оператор распространения в JavaScript.

function choose(choice, ...availableChoices) {
    return availableChoices[choice];
}

choose(2, "one", "two", "three", "four");
// returns "three"

Ответ 5

ECMAScript 6 будет параметры отдыха, которые выполняют то же самое, что и оператор splat.