以下为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/