有点意思的话题: 程序员认知相关

2022-05-07 09:50:44 +08:00
 luffy

近日在 JS 项目开发中有个 array 条件判断,有人这么写:

if (list) {
 // do something
}

我的 code review comment 这么建议:

if (list.length > 0) {
  // do something
}

这时有另一个同事在上面留言说,按他的认知,应该是下面这么写,也就是上面第一种才对。

if (list) {
 // do something
}

这当然只是个非常非常小的问题,甚至都可以忽略不计。

但我联想到一个更有普适性的问题:当这么写代码能跑起来,另一种方式写代码也能跑。那凭什么要用另一种了?

认知 这个词可能很适合用来理解或者解释这类问题。比如这里的 认知: 变量比较 implicitexplicit 的问题。

还有一些其它的例子:

比如,自己在若干年前写代码,当时觉得自己很牛气很完美,而现在再去看,会觉得当时的代码好糟糕。

或者,当别人用 A 用法实现时,你提出用 B 用法更好,别人还得觉得自己的更好。

或者,相反的,当你觉得用 A 方式比较好时,另一个水平更高的说用 B 更好时,你还是坚持已见,觉得别人不懂你。

所有类似的问题,或许都能归结为:认知深度 的差异。这里的认知领域包括:项目工程化,模块化,团队协作,一致性,计算机编译器原理,数学,linux 内核,各种设计模式,不同编程语言各自的特色等。

这里是由一个现实案例联想到的认知问题。那么朋友们,你们有遇到过类似的场景嘛?有的话,不妨举例看看,让我们都来提高下认知吧。当然也包括,在面试或者招聘,会有人关心这类认知问题嘛?

6591 次点击
所在节点    程序员
67 条回复
fstar
2022-05-07 10:25:03 +08:00
以前我觉得 Array.prototype.reduce 不够职责单一,也不怎么用,因为它的语义其实是 “折叠、拍平”,比如将数组的所有数字相加,拍平成一个总和值 sum 。
现在,真香。因为在我眼里,它是优雅的万能数组迭代器。

也算是自己认知成长过程中的一些变化。
下面是 tj 大神写的 node-only 方法,提取对象中的白名单属性,里面就用了 reduce:
https://github.com/tj/node-only/blob/master/index.js
oldshensheep
2022-05-07 10:27:49 +08:00
我上面#17 写的有点小错误,应该是不为 Empty
至于认知问题,还是对语言的理解程度问题(不不不,实际上是语言的坑人程度问题,狗头保命)
codefever
2022-05-07 10:35:16 +08:00
我觉得这不是认知,这是对代码和语言的理解程度不同。
同样是为了飞翔,有人发明了飞艇,有人发明了飞机,都能飞,却是不同的科技点,越往后差距越大。
windyboy
2022-05-07 10:38:50 +08:00
是不是 review 的时候把原因描述清楚也很重要
fyxtc
2022-05-07 10:40:45 +08:00
和认知没关系,和业务和习惯有关系,一定要说的话遵循团队规范就好
belin520
2022-05-07 10:53:42 +08:00
这根本不是 code style 之间的讨论,而是边界 bug 严不严重的讨论
luffy
2022-05-07 10:56:00 +08:00
我的描述有个失误,那个例子是想表达:

```
if (list.length) {
// do something
}
```



```
if (list.length > 0) {
// do something
}
```
devwolf
2022-05-07 10:57:38 +08:00
认知是指每行代码的理解?用意以及实际效果能否对等这样?

我的理解是 if(list) 就是简化的 if(!!list) ,是判断 list 是否转布尔后为 true 。
而 if(list.length>0) 则是 list 中的 length 属性是否大于 0 隐患是 list 可能 undefined ,所以优化+简化写法是 if(list?.length)
if 后面本身有布尔转换了,length 有 0 就会走 else 的逻辑,然后用 可选链操作符?. 进行 list 是否 undefined 的效验拦截


——个人理解
babyoung
2022-05-07 10:59:20 +08:00
那为什么不用 .isArray 呢?
因为比较长吗?
devwolf
2022-05-07 11:01:14 +08:00
#28 补充:

哦,看到楼主#27 的补充描述了。
如果是对比 if( list.length ) 和 if( list.lenght > 0 )的话,后者提高了可读性吧,前者写起来快。我也认为是小问题
IvanLi127
2022-05-07 11:08:41 +08:00
你的 review 结果不对啊,如果原代码是判断是否是数组,不得 ``Array.isArray(list)``,如果确定是数组或是 falsy 的话,那直接 ``!!list`` 或者 ``list`` 也没啥问题。判断 length 是无法确保这货是不是数组。如果判断非空的话,原代码也做不到呀。。。
fsworld
2022-05-07 11:13:53 +08:00
什么是好代码:
1 、可读的:逻辑清晰,bug 难以隐藏
2 、可发布的:统一的异常处理,必要的性能优化,各种情况都有考虑到,健壮性好
3 、可维护的:避免重复,合理的模块划分,易于修改,便于扩展

看法:
1 、代码始终是写给人看的
2 、团队协作,采用大家都在遵守的规范
3 、不断学习,提高自己的认知和见识,知之为知之,不知为不知

tips:另如果不能保证判断的变量是一个数组,如接口返回 null 值,建议:

```
if (Array.isArray(arr) && arr.length) {
// do something
}
```

更建议封装单独的方法,并对其进行单元测试:

```
const isNotEmptyArray = arr => Array.isArray(arr) && arr.length
```
luffy
2022-05-07 11:14:35 +08:00
不好意思,因为正文描述中的失误,导致一开始的讨论都聚集在了 边界条件 判断上了。
具体看 #27 补充说明。

我这里的例子更多是想表达,有人觉得用默认让计算机 自动做隐式转换成 boolean 就可以,而我给的 comment 是,显示用 boolean 做判断。

然后以此抛砖引议,想看下各位有遇到其它情况之类的。
jjwjiang
2022-05-07 11:15:26 +08:00
第一,你的主题里描述的是完全不等价的判断,而你在#27 的补充里说这是你的失误,你想表达的是 length 和 length>0 ,但是这个概念过于基础我觉得已经深入了对 JS 稍有了解的开发者心中,所以我怀疑你自己可能一开始就没搞明白这其中的区别。
第二,.length 和.length>0 在 JS 里就是完全等价的,前者也是非常常规的写法,没有意义也没有必要去讨论这个点
Kenmin
2022-05-07 11:18:58 +08:00
看最新的楼主描述,如果只是检测 Array 非空,我更倾向于第一种写法,第二种太 Java 了
原先的条件判断在 js 里语义完全不同
pianjiao
2022-05-07 11:19:16 +08:00
@murmur 为啥不是 if (list?.length)
pianjiao
2022-05-07 11:19:50 +08:00
@pianjiao 楼上有老哥发过了,没看到
murmur
2022-05-07 11:22:11 +08:00
@pianjiao 我们开发要兼容 IE
duduaba
2022-05-07 11:24:39 +08:00
写多了代码就会改变认知:不是自己负责的项目临时参与的话,只写自己的代码,千万别手贱去东别人的代码,尽管觉得丑陋可能出 bug ,你可以说没责任心。但是这种是最基本的『协作』
zyxyz123
2022-05-07 11:25:26 +08:00
.length 和 .length > 0 都行,就是后者的可读性更强

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851284

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX