有原则的重构

上面的代码是有优化空间的——我们获取 url map 了一次,把这些 url 变为 img 标签又 map 了一次。关于 map 和组合是有定律的:

  1. // map 的组合律
  2. var law = compose(map(f), map(g)) == map(compose(f, g));

我们可以利用这个定律优化代码,进行一次有原则的重构。

  1. // 原有代码
  2. var mediaUrl = _.compose(_.prop('m'), _.prop('media'));
  3. var srcs = _.compose(_.map(mediaUrl), _.prop('items'));
  4. var images = _.compose(_.map(img), srcs);

感谢等式推导(equational reasoning)及纯函数的特性,我们可以内联调用 srcsimages,也就是把 map 调用排列起来。

  1. var mediaUrl = _.compose(_.prop('m'), _.prop('media'));
  2. var images = _.compose(_.map(img), _.map(mediaUrl), _.prop('items'));

map 排成一列之后就可以应用组合律了。

  1. var mediaUrl = _.compose(_.prop('m'), _.prop('media'));
  2. var images = _.compose(_.map(_.compose(img, mediaUrl)), _.prop('items'));

现在只需要循环一次就可以把每一个对象都转为 img 标签了。我们把 map 调用的 compose 取出来放到外面,提高一下可读性。

  1. var mediaUrl = _.compose(_.prop('m'), _.prop('media'));
  2. var mediaToImg = _.compose(img, mediaUrl);
  3. var images = _.compose(_.map(mediaToImg), _.prop('items'));