JavaScript中的Splat运算符是否等效于Python中的* args和** kwargs?


73

我经常使用Python,现在我正在快速学习JavaScript(或者应该说是重新学习)。所以,我想问问,JavaScript*args和的等效之处是什么**kwargs



2
尝试致电function.apply(obj, [args])。每个函数对象都有一个apply()使用上下文(即obj)和参数数组调用函数的方法。
哈特利·布罗迪

为什么不只传递键值对对象?您可以if (key in obj)像使用if arg in kwargspython一样在javascript中进行操作。然后,如果返回true,则可以通过获取值obj[key]
benjaminz 2015年

Answers:


44

最接近的成语*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使用rest参数功能解决了此问题。参见Javascript-'...'的含义


对我而言,直接投入CoffeeScript而不是花时间使用javascript会更容易吗?
Games Brainiac

1
这让我想起了有人问我是否应该直接进入FORTRAN而不是花7090汇编程序花时间的时间。当然,CoffeeScript是一个很好的方法。或TypeScript或Traceur,可为您提供到ECMAScript 6的迁移路径(顺便说一下,语法为function (a, ...optionals))。这些中的任何一个都可以为您提供默认的参数值,而您无需使用与我的答案相同的一些想法使用POJS一起破解它们。

4
找不到ES6链接404
Vidar

36

ES6在JavaScript中添加了一个扩展运算符。

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

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

8
不幸的是,这仅类似于*args并且不能解压缩对象,例如**kwargs
AlexG

2
解压缩对象的类似方法是function choose({choice, ...availableChoices}) {/*...*/}。用法将是:choose({choice: 'a', a: 1, b: 2, c: 3});
eskimwier

该评论确实属于答案
sanderd17年




0

对于那些可能对* 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([“ one”,“ two”,“ three”]):

JavaScript中的相同操作可以通过使用以下命令完成:

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

function(...*args)

**or more dynamically as**

 function(inputs<T>:Array){

   for(index in inputs){

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

function(*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,“ height”:4}]):

同样在JS中

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

function(obj1, obj2){
  ...
}

function(...**kwargs);

**or more dynamically as:**

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

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

function(**kwargs);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.