【问题标题】:JavaScript invoking a function in different waysJavaScript 以不同方式调用函数
【发布时间】:2018-03-21 06:48:49
【问题描述】:
  1. 调用如下函数有什么区别/相似之处?
  2. 有这两种方式的目的是什么?
  3. 它们的优缺点是什么?
  4. 谁能解释一下这个调用是如何工作的 -> sum(2)(3); ?并提及此调用的其他常规等效项?

这两个调用的求和函数可以像下面的代码一样创建

function sum(x) {
  if (arguments.length == 2) {
    return arguments[0] + arguments[1];
  } else {
    return function(y) { return x + y; };
  }
}

console.log(sum(2,3));   // Outputs 5
console.log(sum(2)(3));  // Outputs 5

【问题讨论】:

    标签: javascript jquery html web ecmascript-6


    【解决方案1】:

    取决于上下文,这两种方法同样重要,尽管我猜后一种形式使用较少。什么时候使用一个而不是另一个?很简单,如果您需要传递可立即访问的参数,请使用第一种形式。如果其中一个参数没有改变并且调用者需要一个函数,则使用第二种形式。考虑一下这段代码,我相信它清楚地说明了我的观点:

    function add_direct(a, b) {
        return a + b;
    }
    
    function add_functor(a) {
        return function (b) {
            return a + b;
        }
    }
    
    var nums = [1,4,8];
    
    var add3 = add_functor(3);
    
    console.log(nums.map(add3));
    
    console.log(nums.map(n => {
        return add_direct(3, n);
    }));
    

    它们都加 3,但第二种形式在这里有意义。两者都有自己的长处和短处。希望这能净化空气。

    PS:在 C++ 中,第二种形式称为Functor;其他人称他们为闭包或Function objects

    【讨论】:

      【解决方案2】:
      • 1 和 2: 两者都实现相同的目标。不同之处在于,如果适用,您可以使用后者来减少代码大小。
      • 3:执行速度可能会有所不同。例如array mapping is slower than functor,如果我们使用上面 Rafael 示例的边缘情况。

      • 4:关于函子的讨论通常是正式的和理论的。这样做的原因是,与所有函数式编程技术一样,函子起源于数学,在这种情况下是范畴论。函子定义为:“morphisms between categories” 即函子是定义“fmap”行为的实体,给定一个值和函数“morphism”,将所述函数映射到某个类型的值“category” " 并生成一个新的函子。 所以数组是一个 Functor,因为数组可以被映射。

      简单地说,仿函数是一个值(javascript 中的对象):

      1. 有一个需要函数的 map 方法
      2. 预期的函数可以返回任何类型的值
      3. map 函数将返回另一个相同类型的函子(与原始函子一样)

      您可以找到一些基本示例herehere

      【讨论】:

        【解决方案3】:

        第一种样式只是一个简单的函数调用。

        第二种样式在 x 周围创建一个闭包,并返回一个函数。这个函数可以分配给一个变量供以后使用。例如,您可以使用它来创建一系列具有相同逻辑但每个具有不同闭包的实用函数,如下所示:

        function exponentiate(exponent) {
            return function(number) { return number ** exponent }
        }
        
        var square = exponentiate(2);  // creates a square() function
        var cube = exponentiate(3); // creates a cube() function;
        
        console.log(square(2));
        console.log(cube(2));
        

        另一个方便的技巧是在 DOM 节点集合上生成这些函数的数组(包括闭包中的节点引用) 这允许您在节点集合上调用相同的函数,就像方法调用一样,但不改变它们的原型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-04
          • 2022-01-22
          • 2013-01-21
          • 2015-11-28
          • 2017-03-26
          相关资源
          最近更新 更多