什么时候我应该使用call()而不是直接调用函数

When should I use call() vs invoking the function directly?

本文关键字:函数 调用 我应该 call 什么时候      更新时间:2023-09-26

我有一个JavaScript应用程序,它使用了很多回调。一个典型的函数将接受一个回调,并将其封装在另一个回调中。

Namespace.foo = function( arg, their_on_success ) {
    var my_on_success = function( result ) {
        console.log( 'my_on_success() called' );
        if( 'function' === typeof their_on_success ) {
              their_on_success( result );
        }
    }
    something( arg, my_on_success );
};
在上面的例子中,什么时候应该设置本地call()方法(传递结果变量作为第二个参数)而不是调用their_on_success()并通过函数调用传递结果?

call()用于更改函数的this值:

var obj = {a: 0};
method.call(obj, "parameter");
function method(para) {
    this.a == 0; // true <-- obj is now this
}

使用call(或apply)的唯一原因是如果您想在函数内设置this的值。

嗯,我想apply可以在其他情况下是有用的,因为它接受参数数组

使用函数的call()方法允许您在函数执行期间将绑定到函数的对象更改为this -这也称为上下文

their_on_success.call(myContext, results)

但是,如果您的回调函数不依赖于this,那么您调用它的方式没有区别。

实现一个需要回调的函数就是一个很好的例子。在编写OO代码时,您希望允许调用者指定将调用回调的上下文。

function validateFormAjax(form, callback, context) {
  // Using jQuery for simplicity
  $.ajax({
    url: '/validateForm.php',
    data: getFormData(form),
    success: function(data) {
      callback.call(context, data);
    }
  });
}
请注意,我的示例可以通过将上下文参数传递给$.ajax调用来实现,但这不会向您展示如何使用call

使用call()的另一种情况是,当您处于一个环境中,您不能相信对象自己的方法没有被替换,或者您知道它实际上没有您想要在其上运行的方法。hasOwnProperty通常就是这样一个方法——在很多地方,javascript对象可能没有自己的hasOwnProperty方法,所以作为hasOwnProperty调用它。call(obj, propertyName)是谨慎的

我经常使用"call"的一个场景是拼接参数:

const fn = function() {
    const args = Array.prototype.slice.call(arguments, 0);
    console.log(args);
}

注意arguments是一个对象。然而,args是一个数组。