「以译代学」反讽警告版JavaScript建议:Ninja code

https://javascript.info/ninja-code

在过去的编程🥷使用这些技巧来磨炼代码维护者的思路。

代码审核大师在测试任务会寻找这些技巧。

新手(Novice[ˈnɑvɪs])可能用这些技巧用得更好。仔细阅读,来发现你到底是哪个角色?

反讽警告:许多人尝试这条忍者之路。几乎没有成功。

简洁是智慧的灵魂

尽可能的写短而秀技的代码,来展示你多么聪明。如果你这样写,哪个程序员要是想知道 i 的值,就很美妙了。然后来找你寻求答案。告诉他们,少总是更好的,把他们带到忍者之路。

一个字母的变量

另一种更简洁的编程是在所有地方都用一个字母构成变量名。这样就没有人会在编辑器搜到,就像真实世界的忍者一样,很难被发现。如果真的找到了,他们也不能「解码」出 a、b、c这样的名字代表什么。

不过也有例外。一个真正的忍者从不会在 for 循环里用 i 去计数。i 可以在其他地方,就是不会在这里。看看周围,还有更多国外的字母,比如:x 或 y。

如果一个循环体占到了1-2页,一个国外字母作为循环计数变量是超酷的。因为如果有人想要仔细看看这个循环里面的话,他们将不能在循环计数器里很快就找到 x 的变量。

使用缩写

如果团队规定禁止使用一个字母和模糊的名字,那就缩短他们,构造一些缩写词。

比如:list-> lst, userAgent -> ua, browser -> brsr 等等。

只有有着很好直觉的人才能理解这样的名字。试着缩短一切。只有值得的人才有能力去支持维护你的代码书写。

飞得高,变抽象

“大方无隅,大器晚成;大音希声,大象无形。” 当你在起名字的时候,试着去用一用最抽象的单词。比如说:obj,data,value,item,elem 等等。

一个变量最理想的名字是:data。尽可能在所有地方都使用它。事实上,每个变量都包含数据,对不对?

但是如果 data 已经被用掉了呢?那就试试 value ,它也很普遍。毕竟,一个变量最终是要获得一个值的。

用一个变量的类型来命名:str,num…

试试。一个新人可能会想:这样的名字对忍者来说真的有用吗?事实上,他们确实有用!

当然了,变量名仍然意味着某些事情。它表明了变量里有什么东西:一个字符串,一个数字,或者其他什么东西。但是当一个外来者试图去理解这个代码的时候,他们将会很意外地发现,实际上什么信息都没有!然后最终也将无法再去修改你深思熟虑的(well-thought)代码。
值的类型可以很容易地通过调试(debug)发现。但是变量的意思到底是什么呢?它存的到底是哪个字符串或者数字呢?

不好好冥想,就没有什么方法想明白。

…如果不再有更多的名字呢?就直接加一个数字:data1,item2,elem5等。

聪明的同义词

「道可道,非常道。名可名,非常名。」

对同样的东西使用相似的名字,会让生活变得更有趣,并向公众展示你的创造力。

比如,考虑函数的前缀。如果一个函数在屏幕上展示了一条消息,那就以「display」开头,比如:displayMessage。如果另一个函数在屏幕上展示了其他的东西,比如用户名,就用 「show」开头(比如 showName)。

即便没有什么不同,也暗含这样的函数有某种微妙的(subtle)不同之处。

和团队中的同事忍者们做好约定:如果 John 在他的代码里用 display 开始 「showing」 函数,然后 Peter 可以用 render…,然后 Ann 用 paint…。注意到代码变得超级有趣和多元化了。

…好,然后是帽子戏法!

对于有重要不同点的两个函数,使用同一个前缀!

举例来说,这个函数 printPage(page) 将会使用一个打印机。然后 printText(text) 将会把文本放在屏幕上。让一个不熟悉的读者好好地思考一下相似的函数名 printMessage:”这个函数将会把消息放哪里呢?去一个打印机还是屏幕上?“ 为了让它足够耀眼,printMessage(message) 应当在一个新窗口打印它!

重复使用名字

「始制有名,名亦既有,夫亦將知止,知止所以不殆。」

只在绝对有必要的时候,增加一个新变量。

取而代之的是,重复使用现有的名字。就直接给他们里面写信的值。

在一个函数里,试着只将变量作为参数传递。

这样会让识别变量现在到底是啥变得很难。当然,还有它来自哪里。这个目的是要去发展一个人阅读代码时的直觉和记忆。一个人有着很差直觉的人,将不得不逐行分析一下代码,然后再追踪一个每条代码分支的改变。

一个方法的高级变种是在函数或者循环的中间悄悄地把它的值用一些像的东西替代掉。

比如上图中的代码。「hhhhhh」

想要在第二半函数中继续去使用 elem 的同事将会很意外。只有在调试,测了代码之后,他们才会发现他们一直在跟一个克隆后的变量打交道。

要定期去用。即使面对经验丰富的忍者,也能发挥致命的威力。

来点乐子,加下划线

在变量名前加上 ”_“, “__” 。比如 __name __value。如果你知道他们意思的话就很好。甚至是,就直接为了有趣来加下划线,根本不需要任何的意思。或者在不同的地方有不同的意思。

这招是一石二鸟之计(kill two rabbits with one shot)。首先,代码变得更长和更不容易读懂。其次,一个同行可能会画更久的时间尝试去理解下划线意味着什么。

一个聪明的🥷在代码的一个地方加下划线,并在其他的地方避免(evade)使用。这将会让代码更加脆弱并增加将来错误的可能性。

展示你的爱

让每个人都看到你的实体们是多么非凡卓越!像 superElement-超级元素,megaFrame-超级框架 和 niceItem-好元素 的名字,绝对会让读者受到启发。

事实上,从一方面,确实有些这样的书写:super…, mega…, nice…。但是,从另一方面来看,这什么细节都没有显示。一个读者可能会带薪花费一个或两个小时来寻找一个潜在的意义并思考它们潜在的含义。

重叠外部变量

见上图。一个程序员如果直接跳进去看 render 函数,将会看不到有一个局部的 user 遮住了外部的 user。然后他们将要费劲看看 user,以为它是外部的变量,是 authenticateUser() 的结果。然后,掉到坑里啦!嗨,开始调试吧~

到处都有副作用!

有些函数看起来他们啥没有改变。比如 isReady(), checkPermission(), findTags()…他们被假设去进行计算,发现并返回这个数据,并不改变外部的其他部分。换句话说,没有”副作用“。

一个很漂亮的技巧是除了主要任务,再添加一个”有用的“动作给他们

看到像 is…, check…, find… 这样的函数改变了某些东西之后,你的同事脸上出现的晕眩表情,绝对会拓展你理性的边界。

另一种去让人惊讶的方式是返回一个非标准结果。

展示你的独创性思考!让 checkPermission 的调用返回结果不再是 true / false,而是一个复杂的有着检查结果的对象。

那些试图调用 if(checkPermission(..)) 来写判定的开发者将会好奇为什么这会报错。告诉他们:”看文档去吧!“ 然后给他们看这篇文章。

强大有力的函数!

函数可以做什么不要被函数的名字所限制。更广一点。

比如说,一个叫做 validateEmail(email) 的函数(验证邮件,除了包括检查邮件的正确性)还可以显示报错信息,并请求重新输入这份邮件。

附加的动作不应该从函数名字上很明显地看出来。一个真正的🥷coder将会让他们从代码上也看不怎么出来。

把多个动作结合到一个,会保护你的代码不被再使用。

想象一下,另一个开发者只是想检查一下邮件,同时不输出任何的消息。你的函数

validateEmail(email) 都不会满足他的需求。所以他们也不会因为要问你来打扰你的冥想。

总结

以上每一条建议都来自于真是的代码。有时,甚至是由经验丰富的开发者写的。可能甚至比你还要有经验。

遵循其中的一些,你的代码将充满了惊喜;

大量地遵循他们,你的代码将完全变成你的,没有人将愿意改变它;

完全遵守他们,你的代码代码将会成为年轻开发者们寻找灵感时无比有价值的课程。

【Have you written any of those codes like above?Does it resonate with you?or surprise you?】


了解 小匚的个人博客 的更多信息

订阅后即可通过电子邮件收到最新文章。

了解 小匚的个人博客 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读

了解 小匚的个人博客 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读

退出移动版