Array|从面试考察运算符优先级谈编码规范和管理

前几天在网上看到一篇文章,说是作者在面试中被问到,javascript语言代码“true || false && false”的结果是什么以及具体的原因 。看了那个文章以后,我特意上网查了一下,发现讨论这个问题的类似文章非常多,最早的同题材文章似乎是2016年发表的 。其中一篇文章特别有意思,作者先是根据“true || false && false”的结果,推测出&&运算符的优先级高于||运算符 。这个结论应该说是对的 。其实,这在MDN的javascript运算符优先级表就已经明确说明了 。但作者还做了进一步的实验,分别是“true || alert(2) && false”和“false && false || alert(1)” 。前者的alert(2)不会执行,作者觉得颠覆了自己之前关于优先级的结论 。后者的alert(1)会执行,作者又觉得这与&&和||优先级相同且逻辑短路的假设有冲突 。最后,作者从实际结果出发和一个做JAVA的同事讨论后,推导出一个结论:“遇到||运算符,先去左边的表达式得出结果,如果结果为true,则不会去执行右边的表达式,则短路运算生效;如果结果为false,则去执行右边的表达式,再去根据两边的结果去执行||运算符” 。作者的这个结论既可以说正确,也可以说不正确 。因为,这个结论只是对一种特例的描述 。就好像经典牛顿力学与相对论力学的关系的一样 。靠近通用原理的解释是:运算符的优先级约束的是运算发生的顺序,不约束操作数被取值的顺序;没有特殊约定时,双目运算符总按照自左向右取操作数;当运算符为逻辑运算符时,左操作数取值完成后,经由逻辑短路原则判断后,再评估是否实际进行取右操作数;多运算符存在的长表达式中,操作数的取值过程按照语句生成的语法树的前序遍历原则确定顺序 。
这里,我不是想讨论语言和编译技术的内容 。我是想谈谈,考察具体语言中运算符优先级顺序这类的知识,到底有多少意义 。我们先看一下javascript中的运算符优先级总表:
Array|从面试考察运算符优先级谈编码规范和管理
文章图片
(摘自MDN)
javascript的运算符多达60个,优先级多达20级 。你们确定自己能够一字不落的记忆下来?你们确定愿意去记忆这么多的内容?至少我是不愿意的 。背诵优先级能够解决的问题,我用“()”强制标注优先级就能解决了 。我会更愿意将“true || false && false”这条语句写成“true || (false && false)” 。这样,不仅我自己不容易出现失误,看我代码的人也不需要记忆一堆的优先级,就能准确无误看懂我的代码 。
或许有人会提出,"()"本质也是运算符,加了太多“()”是不是会影响代码运行效率 。对于这个疑问,只能说是多虑了 。现代的编译器,都能在代码优化阶段根据优先级自动脱去不需要的“()” 。即便是作为解释型语言的javascript,也有babel这样的处理工具,可以对代码进行类似编译的处理,脱去多余的运算符 。比如下面的代码:
Array|从面试考察运算符优先级谈编码规范和管理
文章图片
(未经过babel处理的代码)
通过babel进行处理,可以得到下面的结果:
Array|从面试考察运算符优先级谈编码规范和管理
文章图片
(babel处理后的代码脱去了多余的括号)
写代码的目的,是开发出一个产品 。在计算机技术发展的“远古”时期,由于编译器之类工具的能力不强,开发人员通过自身对语言细节的深入掌握来优化代码效率是必要的 。今时今日,软件开发的各种辅助工具的能力已经得到了极大提高,大大释放了开发人员在低价值信息上的记忆压力和劳动力,在代码编写上的“炫技”已经难以让你的产品变得更优秀 。怎样让代码编写的失误率降低,进而提升产品的质量和交付速度,对做好一个产品来说更加有价值 。所以,与其在面试的时候花力气考察应聘者对优先级的记忆,或者培训你的下属在代码语法细节上的深入,不如制定一个更有效的编码规范 。编码规范的意义不仅是从排版格式和命名等方面让代码协作开发时更易于阅读,更重要的是通过一系列的约定,将优秀经验固化下来,让大量的开发者能够快速接受前人的经验减少失误 。
往深了说,这是一个管理意识的问题 。不管是项目的开发管理,还是其他涉及到人员的管理活动,本质都是通过组织群体协作达成一个目标成果 。理论上讲,每个人都可以在他擅长和喜爱的领域成为专家 。但现实来说,你为达成一个目标成果而组织起来的众人里,很多人或因为兴趣不在于此(纯粹为了赚钱糊口接受你的工作)、或因为天赋有限(兴趣和天赋不在一个方向),并不能成为目标领域的专家 。这些人也往往占了团体内人员的大多数,也就是团队内的“一般人” 。汉代贾谊的《过秦论》中提到陈胜吴广时,还特别提到“然陈涉……才能不及中人(一般人)……”,可见“一般人”的标准、以及靠“一般人”能够达到的成果水平,古来就是人们关注重点之一 。韩信能够做到点兵多多益善,能够做到时不时被刘邦抽走他部队里的精兵后仍然能从老弱兵员中带出劲旅,除了他自身兵法的高超外,更在于他对部队的管理能力 。从管理出发,一方面当然要发掘专家专才,让他们起到攻坚和带头作用,另一方面也要通过经验固化下来的执行规范,让大多数一般人能够达成相对较好的成果 。二者相辅相成才能成就你的目标 。而发掘专家专才,一要靠机缘,能不能遇到兴趣和天赋都跟你的目标领域契合的人,二要看你的教练水平和师徒配合度 。孔子弟子三千,也才七十二贤者、达者三人呢,可见这一方面的概率有多低 。所以,制定好的规范,帮助一般人达成好的成果,是日常性管理中非常值得重视的事情 。在软件开发团队的管理中,编码规范的制定、实施、和迭代完善就是值得去花精力做的事情 。当然,软件开发软对的管理中,还有其他诸如工程协作管理、需求分析等类似管理活动值得重点去做,这里我们不再继续展开了 。如果,你一定、一定、一定要坚持你的团队成员都成为专家,请你也记得,即便都是牛人组成的复仇者联盟,打败灭霸时也得靠群殴 。


推荐阅读