Javascript语法 - 类的箭头函数

时间:2016-10-22 23:26:52

标签: javascript reactjs

在网上做了一些教程之后,我偶然发现了一些我不熟悉的奇怪的JavasSript语法。在此tutorial中,作者执行此操作

export default ComposedComponent => class extends 

有人可以向我解释这是什么意思吗?它看起来像一个胖箭头函数,但似乎没有任何参数。它也是多线的,但没有括号。这究竟意味着什么?

2 个答案:

答案 0 :(得分:2)

<强>简介

我们传统上&#34;像这样声明ES6类:

export default class Apple extends Fruit { ... }

Apple只是该类的名称。在您的示例中:

export default ComposedComponent => class extends Component { ... }

只是一个带有参数ComposedComponent的箭头函数和一个匿名类。它基本上等同于:

export default (ComposedComponent) => {
    return class extends Component {
        ...
    }
}

class extends Component是一个未命名的类,它扩展了React&#39; Component

它是什么

这是一个更高阶的组件包装器。您可以将其视为包装另一个组件的React组件 - 组件工厂。它遵循以下语法:

HigherOrderComponentFactory = WrappedComponent: React.Component => NewComponent: React.Component

其中WrappedComponent是被包装的组件,NewComponent是返回的新的更高阶组件 - 都继承自React.Component。现在,如果您查看render方法:

return (
  <ComposedComponent
    {...this.props}
    subscribe={this.subscribe.bind(this)}
    subscriptionReady={this.subscriptionReady.bind(this)}
  />
);

此处,<ComposedComponent {...this.props} />相当于:

React.createElement(ComposedComponent, this.props, null);

<强>应用

让我们再看一下工厂宣言:

export default ComposedComponent => class extends Component { ... }

箭头功能(与上述工厂相当)默认导出,并且参数为ComposedComponent。在这里,ComposedComponent是将由工厂包装的组件,class extends Component { ... }将是新的更高阶组件。

在您的教程中,箭头函数(或HOC工厂)的调用如下:

SubscribeComponent(App)

App是要包装的组件,换句话说就是ComposedComponent。返回的组件是高阶组件。

更多关于高阶组件及其优势的阅读here

答案 1 :(得分:1)

它是一个箭头函数,它有一个参数(ComposedComponent)。 它也是“多线”,但它只是一个声明,因此它不需要括号。

export default ComposedComponent => class extends
Component {
  // ...
}

相同
export default ComposedComponent => class extends Component { ... }

返回的类是匿名的class X extends Component

修改

扩展以下评论:

在这一行上有三件事情可能引起混淆。

export default (ComposedComponent) => {
  return class UnnamedClass extends Component {
    render () {
      return <ComposedComponent />;
    }
  };
}
用这种方式写的,应该更容易看出发生了什么。

  1. 导出语句,导出函数

  2. 一个带有一个参数的箭头函数和一个只是一个返回语句的主体(该语句是否按行拆分)

  3. 构建一个匿名类

  4. 如您所知,箭头函数在有一个参数时不需要括号,当它们只有一个return语句时也不需要括号。

    x => x;
    

    这是真的,即使return语句跨越多行也不能有分号插入。

    () => "1" +
          "2" +
          "3";
    

    哪个地方

    () => class extends
    Component {
      // ...
    }
    

    进来......

    这不是我写的方式,但确实如此。我可能更喜欢这样做:

    () => class extends Component {
      // ...
    }
    

    匹配JS我们都习惯了(虽然装饰者和TS可能会改变它)。

    最后一部分很重要。 除非你把它们放在需要名字的位置,否则这些课程都是匿名的 如果你仔细想想,那就完全有道理了。它们实际上只是早期的构造函数的清理版本,与大多数其他语言的类无关。

    const X = class { constructor () { } };
    const x = new X();
    

    与说

    没什么不同
    const X = function () { };
    const x = new X();
    

    所以

    class X {
      constructor () { }
    }
    

    function X () { }
    

    是等价的。

    你可以传递一个函数的任何地方,期望有人new,你可以传递一个匿名类。

    makeInstance(class {
      a () { }
      b () { }
    });
    

    将所有这些结合在一起,你就得到了

    export default ComposedComponent => class extends
    Component {
      render () {
        return (
          <ComposedComponent >
           // ...
          </ComposedComponent>
        );
      }
    }