在JavaScript中将数组作为函数参数传递


289

我想使用数组作为参数调用一个函数:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

有路过的内容的一种更好的方式x进入call_me()

Answers:


420
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

请参阅MDN文档Function.prototype.apply()


如果环境支持ECMAScript 6,则可以改用传播参数

call_me(...args);

9
附带说明一下,如果有人想传递一个关联数组(命名键),则使用一个对象。来自PHP(并且总是由Google引导到该线程),这花了我一段时间。然后,您可以将整个对象作为参数传递。w3schools.com/js/js_objects.asp
timhc22

感谢您指出“传播”论点!不知道
托马斯

@timhc-您的旁注注释很吸引人,但我无法解析(我是一个通过两个教程工作的javascript noob)。在JS中,根据一些教程,关联数组一个对象。
NateT

@ timhc22,当使用json对象作为参数传递给函数时,请不要忘记参数销毁以获得更好的可读性
Muhammad Omer Aslam

113

为什么不传递整个数组并在函数内部按需处理它?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}

37
这是因为我无法修改call_me()。它是在其他库中定义的,不可能与API混淆。
罗伯特2010年

62
+1,因为即使它不能回答原始问题,也可能是查看此页面的100K +用户所寻找的。
Ishikawa

有人可以解释“ call_me(x)”行在做什么吗?似乎是没有function关键字的函数名称?它到底在做什么?
游泳

1
@swam这是对call_me函数的调用。最后只是缺少一个分号。
SantiBailors

@swam正在执行已声明的call_me(params)函数。
朱利奥·罗德里格斯

43

假设call_me是全局函数,那么您不希望设置此函数。

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);


7

正如@KaptajnKold回答的那样

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

而且您也不需要为call_me函数定义每个参数。你可以用arguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}

4
这是一种糟糕的做法……您将无法查看该功能需要什么,并且如果您查看该功能,则每个参数都是可选的。
罗宾(Robin)

3

注意这个

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

HTML页面

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

可以使用任何Args调用函数

<body onmousemove="FollowMouse(d1,d2)">

要么

<body onmousemove="FollowMouse(d1)">

这显然是答案的一部分。绝对需要“参数”才能在调用后取回数组。谢谢!
FlorianB

2

函数参数也可以是数组:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

当然也可以使用 传播

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)


2

在使用扩展运算符时,我们必须注意,它必须是最后一个或唯一传递的参数。否则它将失败。

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

如果需要将数组作为起始参数传递,则可以执行以下操作:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}

1

您可以以更基本的形式使用扩展运算符

[].concat(...array)

对于返回数组但应作为参数传递的函数

例:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))

0

答案已经给出了,但我只想小菜一碟。您想要实现的目标是method borrowing在JS上下文中调用的,即当我们从一个对象中获取一个方法并在另一个对象的上下文中调用它时。采用数组方法并将其应用于参数是很常见的。让我举一个例子。

因此,我们具有“超级”散列函数,该函数将两个数字作为参数并返回“超级安全”散列字符串:

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

到目前为止,还不错,但是上面的方法没有什么问题,它受限制,只能处理两个数字,这不是动态的,让我们可以处理任何数字,而且不必传递数组(可以如果您仍然坚持)。好了,说够了,让我们战斗吧!

自然的解决办法是使用arr.join方法:

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

天啊。不幸的是,这行不通。因为我们正在调用hash(arguments)和arguments对象,所以它既可迭代又类似于数组,但不是真正的数组。下面的方法怎么样?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

把戏称为 method borrowing.

我们join从常规数组中借用一种方法,[].join.并用于[].join.call在的上下文中运行它arguments

为什么行得通?

这是因为本机方法的内部算法arr.join(glue)非常简单。

从规范中几乎“按原样”得出:

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

因此,从技术上讲,它需要把this [0],this [1]…etc连接在一起。它是故意以允许像这样的任何数组的方式编写的(不是巧合,很多方法都遵循这种做法)。这就是为什么它也可以与this=arguments.

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.