JavaScript 中的 call() 和 apply() VS ()?

JavaScript 是一门功能强大的编程语言,它提供了很多方便的函数调用方式。其中两种函数调用方法就是 call()apply()。它们能够改变函数中的上下文(context),也就是函数内的 this 关键字。而另外一种调用方法是使用函数自身的平凡运算符 (), 本文将详细解释这三种方法的区别和使用场景。

call() 和 apply()

call()apply() 函数非常相似,它们都是用来动态地改变函数中的上下文的。两个函数的第一个参数都是要指定的上下文,剩下的参数则是传递给函数的参数列表。

  • call() 函数以逗号分隔的参数列表的形式传递参数。
  • apply() 函数以数组的形式传递参数。

下面是一个简单的例子:

-------- ----------- -
  ------------------- -------- -- ---- -- ----------------
-

----- ------ - - ----- ------ --

------------------ -------- -- -- ------- ----- -- ---- -- ------
------------------- ---------- -- -- ------- ----- -- ---- -- ------

在这个例子中,我们定义了一个 greet() 函数,然后创建了一个名为 person 的对象,并且拥有一个 name 属性。通过 call()apply() 函数,我们可以将 person 对象作为函数的上下文来调用 greet()。这使得函数内部的 this 关键字指向了 person 对象。

使用 () 运算符

另外一种常见的调用函数的方法是使用函数自身的平凡运算符 (),如下所示:

-------- ----------- -
  ------------------- -------- -- ---- -- ----------------
-

----- ------ - - ----- ------ --

-------------- -- -- ------- ----- -- ---- -- -----------

在这个例子中,我们没有使用 call() 或者 apply() 函数,而是直接调用 greet() 函数本身。结果发现,在函数内部,this.name 返回了 undefined,因为此时的 this 指向了全局作用域,而不是 person 对象。

区别与应用场景

那么,这三种不同的调用方式究竟有什么区别呢?

  • call()apply() 能够显式地指定函数的上下文,而 () 运算符则会使用隐式的上下文。
  • call()apply() 可以传递一个参数列表或者一个数组作为函数的参数,而 () 运算符只能传递逗号分隔的参数列表。

因此,在编写代码时,你需要根据具体的情况来选择使用哪种方式来调用函数。如果你需要显式地指定上下文,或者需要传递数组作为参数,那么就可以使用 call() 或者 apply()。而如果你只需要传递逗号分隔的参数列表,并且不需要显式地指定上下文,那么就可以使用平凡运算符 ()

下面是一个更复杂的例子:

-------- ------ -- -
  ------ - - - - -------
-

----- ---- - - -- -- --
----- ---- - - -- -- --

-- -- ------ --
----- ------- - -------------- -- --- -- -- --
----- ------- - -------------- -- --- -- -- --

-- -- ------- --
----- ------- - --------------- --- ---- -- -- --
----- ------- - --------------- ---

- ---------------------------------------------------------- --------
-------------------------------------------------------------------------------------