原文链接:https://javascript.info/ninja-code,translate with ❤️ by zhangbao.

学而不思则罔,思而不学则殆。 —— 孔子

程序员ninjas过去使用这些技巧来提高代码维护者的思维。

代码审查大师在测试任务中寻找他们。

新手开发人员有时甚至比程序员忍者更好地使用它们。

仔细阅读它们,找出你是谁 - 忍者,新手,或者代码审查员?

⚠️具有讽刺意味的检测

许多人试图追随忍者之路。很少有成功的。

言以简为贵

使代码尽可能短。表现出你有多聪明。

让微妙的语言特征引导你。

举个例子,看一下这个三元运算符:’?’:

  1. // taken from a well-known javascript library
  2. i = i ? i < 0 ? Math.max(0, len + i) : i : 0;

很酷,对吗? 如果你这样写,那么遇到这一行的开发人员试图理解 i 的值是多么快乐。然后来找你,寻求答案。

告诉他,短的总是更好。让他进入忍者的道路。

单个字符变量

The Dao hides in wordlessness. Only the Dao is well begun and well completed. ——老子《道德经》

另一种更快编码的方法是在任何地方使用单字母变量名,像 a,b 或者 c。

一个简短的变量在代码中消失了,就像森林里真正的忍者一样。没有人能够使用编辑器的“搜索”找到它。即使有人做了,也不能“解释”像 a,b 这样的名字表示什么意思。

但是有一个例外。一个真正的忍者永远不会把 i 当作“for”循环中的计数器。任何地方,但不在这里。环顾四周,有许多异国情调的字符,例如 x 或 y。

如果循环体需要 1-2 页(如果可以的话,使它更长),那么一个带有异国情调的变量就特别酷了。然后,如果有人深入到循环中,他就不能很快地发现名为 x 的变量是循环计数器。

使用缩写

如果团队规则禁止使用单字母和模糊的名称来缩短它们,那么就做缩写。

像这样:

  • list → lst。

  • userAgent → ua。

  • brower → brsr。

  • 等等

只有具有真正良好直觉的人才能理解这些名字。尽量缩短一切。只有一个有价值的人应该能够维护你的代码的开发。

飞得很高, 是抽象的

The great square is cornerless
The great vessel is last complete,
The great note is rarified sound,
The great image has no form. —— 老子《道德经》

在选择一个名字的时候,试着使用最抽象的词。像 obj,data,value,item,elem 等等。

  • 理想名字是 data。可以在任何地方使用,确实,什么变量不是数据呢,对吧?

但是,如果 data 已经被采用,该怎么办呢?尝试 value,它也是普遍的。毕竟,一个变量最终会得到一个值。

  • 通过类型来命名变量:strnum

试一试。 一位年轻的创始人可能会怀疑 - 这样的名字真的对忍者有用吗?的确,他们是!

当然,变量名仍然意味着什么。它说变量里面有什么:字符串,数字或其他东西。但是当一个局外人试图理解代码时,他会惊讶地发现实际上根本就没有信息!最终将无法改变您精心设计的代码。

通过调试很容易找到值类型。但变量的含义是什么?它存储哪个字符串/数字?

没有好的冥想就没有办法弄明白!

  • 但是如果没有更多这样的名字呢?只要加上一个数字:data1item1elem5 等。

注意力测验

只有真正细心的程序员才应该能够理解您的代码。但是如何检查呢?

其中一种方法——使用类似的变量名,比如 date 和 data。

把它们混合在一起。

快速阅读这类代码是不可能的。当有一个印刷错误的时候。嗯。我们被困了很长时间,喝了茶。

聪明的同义词

The hardest thing of all is to find a black cat in a dark room, especially if there is no cat. ——孔子

相似的名字来做同样的事情会让生活更有趣,并向公众展示你的创造力。

例如,考虑函数前缀。如果一个函数在屏幕上显示一条消息——以 diaplay… 开头,像 displayMessage。然后,如果另一个函数在屏幕上显示其他东西,比如用户名,那么就以 show 开头(像 showName)。

暗示这些功能之间有细微的差别,但却没有。

与团队的其他忍者们达成协议:如果约翰在代码里以 display… 开头来写“显示”函数……,彼得使用 render..,还有安——paint……请注意,代码变得更加有趣和多样化。

现在是帽子戏法!

例如,函数 printPage(page) 将使用打印机。 而 printText(text) 函数会将文本放在屏幕上。让一个不熟悉的读者仔细思考类似命名的函数 printMessage:“它在哪里放置消息?到打印机或屏幕上?”为了让它真正闪耀,printMessage(message) 应该在新窗口中输出它!

重用名称

Once the whole is divided, the parts
need names.
There are already enough names.
One must know when to stop. ——老子《道德经》

仅在绝对必要时添加新变量。

相反,重用现有名称。只需在其中写入新值即可。

在函数中尝试仅使用作为参数传递的变量。

这将使现在很难确定变量中的确切内容。它也来自哪里。直觉较弱的人必须逐行分析代码并跟踪每个代码分支的变化。

该方法的一个高级变体是隐蔽地(!)在循环或函数的中间用类似的东西替换值。

例如:

  1. function ninjaFunction(elem) {
  2. // 20 lines of code working with elem
  3. elem = clone(elem);
  4. // 20 more lines, now working with the clone of the elem!
  5. }

想要在函数的后半部分使用 elem 的同事程序员会感到惊讶……只有在调试过程中,在检查代码后他才会发现他正在使用克隆!

甚至对经验丰富的忍者也有致命的效果。经常在代码中看到。

下划线乐趣

在变量前面加 或者 __,像 _name 或 __value。如果你知道他们的意思,那就太好了。或者,更好的是,把它们加起来只是为了好玩,没有特别的意义。或者在不同的地方有不同的含义。

你一枪杀了两只兔子。 首先,代码变得更长,更不易读,第二,同事开发人员可能花费很长时间试图找出下划线的含义。

一个聪明的忍者将下划线放在一个代码点,并在其他地方躲避它们。 这使得代码更加脆弱,并增加了未来错误的可能性。

表达你的爱

让每个人都看到你的实体是多么壮观! 像superElement,megaFrame和niceItem这样的名字肯定会启发读者。

事实上,从一方面来说,有些东西是写的:super……,mega……,nice……但另一方面 - 没有带来任何细节。 读者可能会决定寻找隐藏的意义并冥想一两个小时。

重叠的外部变量

When in the light, can’t see anything in the darkness.
When in the darkness, can see everything in the light. —— Guan Yin Zi

对函数内外的变量使用相同的名称。一样简单。不需要努力。

  1. let user = authenticateUser();
  2. function render() {
  3. let user = anotherValue();
  4. ...
  5. ...many lines...
  6. ...
  7. ... // <-- a programmer wants to work with user here and...
  8. ...
  9. }

一个在 render 中跳跃的程序员可能没有注意到有一个本地用户跟踪外部的用户。

然后,他会尝试与 user 一起工作,假设它是外部变量,是 authenticateUser()的结果。陷阱就会出现!你好,调试器……

到处都有副作用

有些功能看起来不会改变任何东西。 像isReady(),checkPermission(),findTags()……假设它们执行计算,查找并返回数据,而不更改它们之外的任何内容。 换句话说,没有“副作用”。

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

当他看到一个名为 is… 的函数,check…..或者 find……改变某些东西时,他会在你的同事面前表达茫然的惊讶 - 这肯定会扩大你的理性界限。

另一种令人惊讶的方法是返回非标准结果。

展现你的原始思维! 让 checkPermission 的调用返回不是 true/false,而是一个带有检查结果的复杂对象。

那些尝试编写 if( checkPermission(..) ) 的开发人员会想知道为什么它不起作用。告诉他们:“阅读文档!”。并给出这篇文章。

强大的函数

he great Tao flows everywhere,
both to the left and to the right. ——老子《道德经》

不要通过名称中的内容来限制功能。 更广泛。

例如,函数 validateEmail(email) 可以(除了检查电子邮件的正确性)显示错误消息并要求重新输入电子邮件。

功能名称中不应显示其他操作。 一个真正的忍者编码器也会使代码不明显。

将多个操作合并为一个可以保护您的代码不被重用。

想象一下,另一位开发人员只想检查电子邮件,而不是输出任何消息。 你的函数 validateEmail(email)这两个都不适合他。 所以他不会通过询问任何事情来打破你的冥想。

总结

上面的所有“建议”都来自真实的代码…有时,由经验丰富的开发人员编写。 也许比你更有经验;)

  • 关注其中一些,您的代码将充满惊喜。

  • 关注其中的许多内容,您的代码将真正成为您的代码,没有人愿意更改它。

  • 全部跟进,您的代码将成为寻求启发的年轻开发人员的宝贵经验。

(完)