首页 > loadsh 源码阅读 问题 001

loadsh 源码阅读 问题 001

以下为loadsh源码中的一段:

  function baseCompareAscending(value, other) {
    if (value !== other) {
      var valIsReflexive = value === value,
          othIsReflexive = other === other;

      if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) {
        return 1;
      }
      if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) {
        return -1;
      }
    }
    return 0;
  }

比较大小。

问题一, 代码写法问题, 为什么不写成下面代码这种形式,在我看来两种写法是等价的,但是下面的精简了一层{}
,上面的那个写法我没有看出其他的含义

  function baseCompareAscending(value, other) {
      if (value === other) return 0;

      var valIsReflexive = value === value,
          othIsReflexive = other === other;

      if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) {
        return 1;
      }
      if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) {
        return -1;
      }
    }

问题2:
除了NaN的情况外,是否还存在 value === value 为 false的情况?


在我看来两种写法是等价的,,但是下面的精简了一层{}

是等价的。你的做法,在重构一书中被成为 Guard clause,是一种常见的重构方法。
从代码质量看,被重构领域认为是更好的代码。也更加符合契约编程的精神。
{显然,我弄错了。多谢指正}
"{} ~== {} " ,防不胜防。

为什么不写成下面代码这种形式

高手也有小毛病。笨蛋也非无处不可取。重构业界认可的,也并非定论。在小圈子内,可以通过代码标准的方式约定。大圈子内,做此事带来的纷争甚多,得不偿失。


如 @limichange 所述,后面一种写法没有完整覆盖所有情况,一个简单的例子是涉及对象的时候baseCompareAscending({},{})

关于a === a //false的情况确实只有NaN一种可能,可以看看ECMA标准中关于严格比较的描述。在类型和值都相同的条件下只有NaN会返回false


额,按下面的话,岂不是在不满足所有if的时候就会不返回值了?
上面的写法是绝对有返回值,上面的写法更加健壮。
http://jsfiddle.net/dbu9Ltja/


题主,我想给你一个建议。Lodash 是有单元测试的,如果你觉得某个方法的写法可以改进,那么在你提出疑问或者提交 PR 之前,先用你的写法跑一下单元测试,能通过自然证明你是有道理的(但不一定是 100% 正确,因为单元测试也有不够健壮的特例)。实际上阅读任何源代码(成熟的项目)都应该遵循这样的方式,如果对方没有测试覆盖,你也可以尝试自己一边读代码一边写测试来印证自己的理解。而到了给项目贡献代码的时候,编写单元测试更是必须的,Github 上很多项目在提交 PR 的时候都要求有单元测试覆盖的,否则项目的质量很难得到保障,项目的管理者可没有空逐个去检查 PR 的逻辑是否正确和完备。

就本问题来说,你的写法并没有覆盖到所有的条件分支(如楼上所示),作为判断式的函数是一定需要返回值的,所以要特别小心 Guard Clause 的使用。

至于第二个问题,看这里:http://dorey.github.io/JavaScript-Equality-Table/

【热门文章】
【热门文章】