JavaScript中使用参数调用apply方法

19
我想使用javascript的apply()方法来调用一个函数。如果这个函数没有参数,那么这样做是可以的。例如:
function test()
{
  console.log(this);
}

body = document.getElementsByTagName("body")[0]; // shortcut to body element

test.apply(body); // returns [object HTMLBodyElement]

但是我无法做到同样的事情来调用带有参数的函数:

function test(msg)
{
  console.log(msg);
}

body = document.getElementsByTagName("body")[0]; // shortcut to body element

test(this).apply(body); // mysteriously returns the correct result, then
// typeError: 'undefined' is not an object (evaluating "test(this).apply".

上面的例子非常简单,但我的问题是:如何使用apply()方法来调用带有参数的函数。
5个回答

32

apply 函数接受两个参数:

test.apply(null, [body]);

第一个参数设置函数执行时的this值。第二个参数是该函数的参数数组。

在您的示例中,您可以将其重写为以下内容:

function test() {
    console.log(this);
}

并按照以下方式进行调用:

test.apply(this);

需要注意的是第二个参数应该是一个数组,而不仅仅是单个元素。test.apply(null, body) 在我的浏览器(Chrome 35)中会出错,但是 test.apply(null, [body]) 可以正常工作。 - FeifanZ
使用apply方法的真正用途是什么?有什么好处吗? - Thunder
1
我相信有很多真正的用途。其中一些想到的是猴子补丁函数(包括内置函数),可变参数函数,以及为回调函数指定this - John Keyes
@JohnKeyes,假设我有一个函数 function test(msg){..},我需要设置 this 值,并且只想在 msg 中获取消息值? test.call(newThisObj,'new this obj set'); 值将在 arguments 中而不是 msg 中可用。 - techie_28
@techie_28,你可以使用以下代码:test.apply(this, ['new this obj set']); - John Keyes

8
首先要注意的是,你实际上是立即调用了你的函数,这行代码:
test(this).apply(body);

起初你调用test函数时将this作为参数传递,然后尝试访问函数结果的apply属性。但是,你的函数没有返回任何内容,所以它的结果是undefined
那么,在undefined值上访问这个属性会导致TypeError异常。
现在,让我们看看实际上你想要做什么,如果你想把body变量的值作为函数的参数,并将外部this值设置为test函数的this值,你可以这样做:
test.apply(this, [body]);

但这也是为什么call方法存在的原因,当你知道要传递哪些参数时,你不需要为了创建数组而无所事事,只需传递参数即可:

test.call(this, body);

apply方法在处理动态数量的参数时非常有用,当您知道要传递哪些参数并仍然具有设置this值的能力时,call是您所需的。


call 的文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call - John Keyes

6

@JohnKeyes是对的,我应该更注意我的复制和粘贴。我已经纠正了语法错误。 - bittersweetryan
如果您愿意,我可以删除这里的评论。它们并没有对答案有所贡献。 - John Keyes

0

请确保添加参数:

test.apply(body, ["my message here"]);

0

apply 可以接受两个参数

  1. 要绑定的对象

  2. 传递给方法的参数数组

    test.apply(obj, arr);

在这种情况下,obj 是 body,arr 是参数数组。

记得在调用的函数中接受这些参数,如下所示:

function test(...params)
 {
   console.log(this);
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接