首页 文章

多个箭头函数在javascript中意味着什么?

提问于
浏览
252

我一直在阅读一堆 react 代码,我看到这样的东西,我不明白:

handleChange = field => e => {
  e.preventDefault();
  /// Do something here
}

4 回答

  • 31

    That is a curried function

    首先,用两个参数检查这个函数......

    let add = (x,y) => x + y;
    add(2,3); //=> 5
    

    这里再次以咖喱形式......

    let add = x => y => x + y;
    

    这是没有箭头功能的相同code1 ...

    let add = function (x) {
      return function (y) {
        return x + y;
      };
    };
    

    Focus on return

    以另一种方式可视化它可能会有所帮助 . 我们知道箭头函数的工作方式是这样的 - 让我们特别注意 return value .

    let f = someParam => returnValue
    

    所以我们的 add 函数返回一个函数 - 我们可以使用括号来增加清晰度 . bolded 文本是函数 add 的返回值

    let add = x => (y => x + y)
    

    换句话说,某些数字的 add 返回一个函数

    add(2) // returns (y => 2 + y)
    

    Calling curried functions

    所以为了使用我们的curried函数,我们不得不称之为有点不同......

    add(2)(3); // returns 5
    

    这是因为第一个(外部)函数调用返回第二个(内部)函数 . 只有在我们调用第二个函数之后才能实际获得结果 . 如果我们将呼叫分成两行,这就更明显了......

    let add2 = add(2); // returns function(y) { return 2 + y }
    add2(3);           // returns 5
    

    Applying our new understanding to your code

    相关:“绑定,部分应用和currying有什么区别?”

    好了,现在我们了解它是如何工作的,让我们来看看你的代码

    handleChange = field => e => {
      e.preventDefault();
      /// Do something here
    }
    

    我们将从不使用箭头功能代表它开始......

    handleChange = function(field) {
      return function(e) {
        e.preventDefault();
        // Do something here
        // return ...
      };
    };
    

    但是,因为箭头函数在词法上绑定 this ,它实际上看起来更像是......

    handleChange = function(field) {
      return function(e) {
        e.preventDefault();
        // Do something here
        // return ...
      }.bind(this);
    }.bind(this);
    

    也许现在我们可以更清楚地看到这一点 . handleChange 函数正在为指定的 field 创建函数 . 这是一种方便的React技术,因为您需要在每个输入上设置自己的侦听器才能更新应用程序状态 . 通过使用 handleChange 函数,我们可以消除导致为每个字段设置 change 侦听器的所有重复代码 .

    很酷!


    1这里我没有词法绑定 this 因为原始 add 函数不使用任何上下文,所以在这种情况下保留它并不重要 .

  • 29

    了解available syntaxes of arrow functions将使您了解在您提供的示例中'chained'时所引入的行为 .

    如果在没有块括号的情况下编写箭头函数(包含或不包含多个参数),则会隐式返回构成函数体的表达式 . 在您的示例中,该表达式是另一个箭头函数 .

    No arrow funcs              Implicitly return `e=>{…}`    Explicitly return `e=>{…}` 
    ---------------------------------------------------------------------------------
    function (field) {         |  field => e => {            |  field => {
      return function (e) {    |                             |    return e => {
          e.preventDefault()   |    e.preventDefault()       |      e.preventDefault()
      }                        |                             |    }
    }                          |  }                          |  }
    

    使用箭头语法编写匿名函数的另一个优点是它们在词汇上与它们定义的范围绑定 . 来自'Arrow functions' on MDN

    与函数表达式相比,箭头函数表达式具有更短的语法,并以词汇方式绑定此值 . 箭头功能始终是匿名的 .

    考虑到它来自reactjs应用程序,这在您的示例中尤为重要 . 正如@naomik所指出的,在React中,你经常使用 this 访问component's member functions . 例如:

    Unbound                     Explicitly bound            Implicitly bound 
    ------------------------------------------------------------------------------
    function (field) {         |  function (field) {       |  field => e => {
      return function (e) {    |    return function (e) {  |    
          this.setState(...)   |      this.setState(...)   |    this.setState(...)
      }                        |    }.bind(this)           |    
    }                          |  }.bind(this)             |  }
    
  • 414

    一般提示,如果您对任何新的JS语法及其编译方式感到困惑,可以查看babel . 例如,在babel中复制代码并选择es2015预设将得到这样的输出

    handleChange = function handleChange(field) {
     return function (e) {
     e.preventDefault();
      // Do something here
       };
     };
    

    babel

  • 44

    可以这样想,每次看到箭头时,都要用 function 替换它 .
    function parameters 在箭头前定义 .
    所以在你的例子中:

    field => // function(field){}
    e => { e.preventDefault(); } // function(e){e.preventDefault();}
    

    然后在一起:

    function (field) { 
        return function (e) { 
            e.preventDefault(); 
        };
    }
    

    From the docs

    // Basic syntax:
    (param1, param2, paramN) => { statements }
    (param1, param2, paramN) => expression
       // equivalent to:  => { return expression; }
    
    // Parentheses are optional when there's only one argument:
    singleParam => { statements }
    singleParam => expression
    

相关问题