React中的ChainedFunction

之前提到过,React通过Mixin机制实现了类的多重继承,而当类从多个父类继承方法时,就有可能出现同名方法在多个Mixin中被定义的情况,这时应该如何处理呢?
React中通过SpecPolicy和ChainedFunction进行了处理。

SpecPolicy

ReactCompositeComponent文件中定义了一个枚举对象SpePolicy,它包含三个属性, 分别是

  • DEFINE_ONCE
  • DEFINE_MANY
  • DEFINE_BASE

与此同时,在React还定义了ReactCompositeComponentInterface,并在接口中定义了一些方法和属性的SpecPolicy。

当基类从Mixin继承某个属性/方法时,会查询它的SpecPolicy进行检测:

  1. 如果ReactCompositeComponentMixin中定义了同名属性,那么该属性的SpecPolicy不能为OVERRIDE_BASE
  2. 如果该类的原型对象上面存在同名属性,那么该属性的SpecPolicy必须为DEFINE_MANY
  3. DEFINE_ONCE的属性不能在多个Mixin中同时出现

ChainedFunction

当一个方法同时在多个Mixin中定义了,并且其SpecPolicy为DEFINE_MANY时,如何保证每个Mixin中的同名函数都被执行了呢?

答案是使用ChainedFunction。多个Mixin中的同名函数,会通过调用createChainedFunction方法,覆盖proto中原有的同名函数,将createChainedFunction的返回值作为新的同名函数存储到proto中。如果之后再出现了同名函数,重复刚才的步骤,将创建的chainedFunction和新的同名函数作为参数,再创建一个ChainedFunction。

createChainedFunction源码如下:

function createChainedFunction(one, two) {
  return function chainedFunction(a, b, c, d, e, tooMany) {
    invariant(
      typeof tooMany === 'undefined',
      'Chained function can only take a maximum of 5 arguments.'
    );
    one.call(this, a, b, c, d, e);
    two.call(this, a, b, c, d, e);
  };
}

在React中能看到很多形参限制在5个以内的写法,这其实很科学,参数列表过长,不容易记住其调用形式。

Show Comments

Get the latest posts delivered right to your inbox.