Fir*_*row 159 javascript variadic-functions
是否可以从数组中向JavaScript函数发送可变数量的参数?
var arr = ['a','b','c']
var func = function()
{
// debug
alert(arguments.length);
//
for(arg in arguments)
alert(arg);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
Run Code Online (Sandbox Code Playgroud)
我最近写了很多Python,这是一个很好的模式,能够接受varargs并发送它们.例如
def func(*args):
print len(args)
for i in args:
print i
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'
Run Code Online (Sandbox Code Playgroud)
在JavaScript中是否可以发送一个数组作为参数数组?
CMS*_*CMS 182
使用申请:
func(...arr);
Run Code Online (Sandbox Code Playgroud)
请注意,apply它用作apply的第一个参数,它将this关键字设置为内部的Global对象(窗口)apply.
另请注意,该this对象实际上不是一个数组,您可以通过以下方式对其进行转换:
function func(...args) {
args.forEach(arg => console.log(arg))
}
const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
也许对您有用,您可以知道函数需要多少个参数:
function func(first, second, ...theRest) {
//...
}
Run Code Online (Sandbox Code Playgroud)
但无论如何你可以传递任意数量的参数......
dan*_*ben 73
您实际上可以将任意数量的值传递给任何javascript函数.显式命名的参数将获得前几个值,但ALL参数将存储在arguments数组中.
要以"unpacked"形式传递arguments数组,您可以像使用apply一样使用apply(cf Functional Javascript):
var otherFunc = function() {
alert(arguments.length); // Outputs: 10
}
var myFunc = function() {
alert(arguments.length); // Outputs: 10
otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
Run Code Online (Sandbox Code Playgroud)
Tgr*_*Tgr 22
该图示和传播运营商ES6,使用Javascript的计划下一个版本的一部分.到目前为止只有Firefox支持它们.此代码适用于FF16 +:
var arr = ['quick', 'brown', 'lazy'];
var sprintf = function(str, ...args)
{
for (arg of args) {
str = str.replace(/%s/, arg);
}
return str;
}
sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');
Run Code Online (Sandbox Code Playgroud)
注意传播的awkard语法.常用的语法的sprintf('The %s %s fox jumps over the %s dog.', ...arr);是还不支持.您可以在此处找到ES6兼容性表.
for...of另请注意另外ES6 的使用.使用for...in数组是一个坏主意.
ES2015有两种方法.
arguments对象该对象内置于函数中,它适当地引用函数的参数.但是,从技术上讲,它不是一个数组,所以典型的数组操作不适用于它.建议的方法是使用Array.from或扩展运算符从中创建数组.
我已经看到其他答案提到使用slice.不要那样做.它会阻止优化(来源:MDN).
Array.from(arguments)
[...arguments]
Run Code Online (Sandbox Code Playgroud)
但是,我认为这arguments是有问题的,因为它隐藏了函数接受的输入.一个arguments功能通常是这样写的:
function mean(){
let args = [...arguments];
return args.reduce((a,b)=>a+b) / args.length;
}
Run Code Online (Sandbox Code Playgroud)
有时,函数头像下面这样编写,以类似C的方式记录参数:
function mean(/* ... */){ ... }
Run Code Online (Sandbox Code Playgroud)
但这种情况很少见.
至于为什么它有问题,以C为例.C向后兼容一种称为K&R C的古老的ANSI前语言.K&R C允许函数原型具有空参数列表.
int myFunction();
/* This function accepts unspecified parameters */
Run Code Online (Sandbox Code Playgroud)
ANSI C为varargs(...)提供了一个工具,并void指定了一个空参数列表.
int myFunction(void);
/* This function accepts no parameters */
Run Code Online (Sandbox Code Playgroud)
许多人无意中使用unspecified参数list(int myfunction();)声明函数,当他们期望函数采用零参数时.这在技术上是一个错误,因为该函数将接受参数.任意数量的.
C中的适当varargs函数采用以下形式:
int myFunction(int nargs, ...);
Run Code Online (Sandbox Code Playgroud)
JavaScript实际上确实有类似的东西.
实际上,我已经向你展示了传播运营商.
...name
Run Code Online (Sandbox Code Playgroud)
它非常通用,也可以在函数的参数列表("休息参数")中使用,以一种很好的文档方式指定varargs:
function mean(...args){
return args.reduce((a,b)=>a+b) / args.length;
}
Run Code Online (Sandbox Code Playgroud)
或者作为lambda表达式:
((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3
Run Code Online (Sandbox Code Playgroud)
我更喜欢传播运营商.它干净,自我记录.
该apply函数有两个参数; 对象this将绑定到,并且参数用数组表示.
some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
Run Code Online (Sandbox Code Playgroud)
它被称为splat运营商.你可以在JavaScript中使用apply:
var arr = ['a','b','c','d'];
var func = function() {
// debug
console.log(arguments.length);
console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr);
Run Code Online (Sandbox Code Playgroud)