【问题标题】:When should I use call() vs invoking the function directly?我什么时候应该使用 call() 与直接调用函数?
【发布时间】:2011-12-11 03:47:13
【问题描述】:

我有一个使用大量回调的 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()方法(将结果var作为第二个参数传递)而不是调用their_on_success()并通过函数调用传递结果?

【问题讨论】:

    标签: javascript unobtrusive-javascript


    【解决方案1】:

    我经常使用“调用”的一个场景是拼接参数:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我明白你在说什么,但我认为它可以改进。比如:JavaScript 允许你完全不指定原型 (Object.create(null)),覆盖原生对象原型上的属性,甚至是对象本身。因此,为了安全起见,您的代码应该使用Object.prototype.hasOwnProperty.call(obj, 'someProp') 以防弹。
      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        function validateFormAjax(form, callback, context) {
          // Using jQuery for simplicity
          $.ajax({
            url: '/validateForm.php',
            data: getFormData(form),
            success: function(data) {
              callback.call(context, data);
            }
          });
        }
        

        请注意,我的示例可以通过将 context 参数传递给 $.ajax 调用来实现,但这不会向您展示如何使用 call

        【讨论】:

          【解决方案5】:

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

          their_on_success.call(myContext, results)
          

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

          【讨论】:

            【解决方案6】:

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

            好吧,我猜apply 在其他情况下可能很有用,因为它接受参数数组。

            【讨论】:

            • apply 的主要情况是处理可变参数时,因此您只需将arguments 传递给它。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-16
            相关资源
            最近更新 更多