88

我经常使用 Python,而且我现在正在快速学习 JavaScript(或者我应该说重新学习)。所以,我想问一下,JavaScript中的*argsand是什么意思?**kwargs

4

6 回答 6

55

最接近的成语*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 */
}

如果您想使用语法糖,请编写一个函数,将一个函数转换为另一个使用必需参数和可选参数调用的函数,并将所需参数以及任何其他可选参数作为最终位置的数组传递:

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 用剩余参数特性解决了这个问题。见Javascript - '...' 的意思

于 2013-06-29T14:18:09.117 回答
50

ES6 为 JavaScript 添加了扩展运算符。

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

choose(2, "one", "two", "three", "four");
// returns "three"
于 2015-02-22T00:24:09.753 回答
18

我在这里找到了一个很好的解决方案: http ://readystate4.com/2008/08/17/javascript-argument-unpacking-converting-an-array-into-a-list-of-arguments/

基本上,使用function.apply(obj, [args])而不是function.call. apply 将数组作为第二个参数并为您“splats”它。

于 2013-11-12T19:28:36.860 回答
8

最接近的等价物是arguments伪数组

于 2013-06-29T12:46:17.997 回答
2

ECMAScript 6 将具有与 splat 运算符相同的其余参数。

于 2014-08-27T21:50:45.407 回答
2

对于那些可能对 *args 和 **kwargs 魔法变量有些迷茫的人,请阅读http://book.pythontips.com/en/latest/args_and_kwargs.html

总结: *args 和 **kwargs 只是编写魔法变量的常规方式。您可以只说 * 和 ** 或 *var 和 **vars。也就是说,让我们谈谈 2019 年的 JavaScript 等价物。

python 中的 *args 表示一个 JavaScript 数组,例如 ["one", "two", "three"] 将其传递给 python 函数,您只需将函数定义为 def function_name(*args):表示此函数接受“数组”或“如果你想列出”来调用你只需使用函数 function_name(["one", "two", "three"]):

JavaScript 中同样的事情可以通过使用来完成:

function func(x,y,z){
  ...
}
let args = ["one", "two", "three"];

func(...args)

**or more dynamically as**

 function func(inputs<T>:Array){

   for(index in inputs){

      console.log(inputs[index]);
   }
}
let args = ["one", "two", "three"];

func(args)

看看https://codeburst.io/a-simple-guide-to-destructuring-and-es6-spread-operator-e02212af5831

另一方面,**kwargs 仅表示键值对(对象)的数组,仅此而已。因此 **kwargs 例如是 [{"length": 1, "height": 2}, {"length":3, "height": 4}]

在python中定义一个接受对象数组的函数,你只需说 def function_name(**kwargs): 然后调用它你可以做 function_name( [{"length": 1, "height": 2}, {"length": 3、“身高”:4}]):

同样在 JS

const kwargs = [{"length": 1, "height": 2}, {"length":3, "height": 4}]

function func(obj1, obj2){
  ...
}

func(...kwargs);

**or more dynamically as:**

const kwargs = [{"length": 1, "height": 2}, {"length":3, "height": 4}]

function func(obj){
  for(const [key, value] of Object.entries(obj)){
    console.log(key, ": ", value)
 }

func(kwargs);
于 2019-10-24T14:07:18.037 回答