阅读下列代码

  1. let a = 10;
  2. let b = a;
  3. a = 0;

在运行后 ab 的值分别是多少?在阅读下面的内容前在你的脑海里演算一下。

如果你已经写了一段时间的 javascript 的话,你可能会认为:“这段代码比我平时写的简单多了,它的关注点是什么呢?”

这段练习的目的并不是给你介绍变量。我们假设你对它们已经很熟悉了,相反,这里时为了让你注意和反思你的心智模型。

什么是心智模型?

请再次阅读上面的代码并且认真思考结果是什么。(我们会在之后发现为什么这个意图会如此的重要)

当你第二次阅读以上代码时,请密切关注脑海里考虑的东西,你也许注意到如下的独白:

  • let a = 10;
    • 声明一个名为a的变量,设置为10
  • let b = a;
    • 声明一个名为b的变量,设置为a
    • 等等,发生了什么?噢,a是10,所以b也是10
  • a = 0;
    • 设置变量a的值为0
  • 所以现在a是0,并且b也是0,这就是我们的答案

也许你的独白有一点不一样。也许你会说是“赋值”而不是“设置”,也许你阅读的顺序不一致,也许你得到了不一样的结果。注意这到底有什么不一样。当然,这份独白也许并没有捕捉到你脑海中真正发生的事情,你也许会说“将b的值赋值为a”,但是赋值一个变量真正意味什么呢?

你也许能在每个熟悉的基本编程概念和操作中找到此类信息(比如变量、给变量赋值),这与你能联想到这些有着根深蒂固的类比。其中一部分来源于现实世界,其他的也许来自于你之前学习的其他领域,比如数学中数字。这些类型也许会有交集,更有甚者会互相覆盖,但是它们仍然能够帮助你了解上述代码中发生了什么。

举个例子,许多人首先将变量理解为可以放入东西的“盒子”。甚至在看到变量后不再联想到“盒子”,你也能在脑海中构建出“盒子似”的样子。在你脑海里构建的这些近似的东西就是“心智模型”。如果你已经编程了很长时间,这可能会很困扰,但是请尝试注意并反省你的心智模型,它们可能是视觉、空间、机器模型等的组合。

这些直觉(比如变量的“盒子性”)将会影响着我们一生阅读代码的方式。但是有时候我们的心智模型是错误的,也许我们早期阅读的教程为了更容易解释而牺牲了正确性;也许是我们以前学习的其他语言的使我们错误地转移了对某种语言特性的直觉,比如this;也许我们从一些代码片段中推断出了心智模型,但是从来没有验证过它的正确性。

识别和修正这些问题便是Just JavaScript要做的事情。我们将建设或者重建你的javascript心智模型为正确的且有用的。一个良好的心智模型将会帮助你更快的发现和修正bug,更好的理解其他开发者的代码,并且对你自己的代码更为自信。

(顺便说一句,a的值为0b的值为10是正确答案)

编码,快和慢

“思考,快和慢”是Daniel Kahneman的一本广受欢迎的书籍。它的中心论点是说人在思考时会有两种不同的系统。

只要我们可以,我们都会优先选择“快”系统。我们和很多动物共享这个系统,它给了我们令人惊讶的力量,比如走路的时候不摔倒。这个“快”系统善于模式匹配(生活所必备!)和“直觉反应”。但是不善于计划。

得益于前额叶的发展,人类同时拥有了“慢”系统。这个“慢”系统负责一步一步的、复杂的推理。这让我们计划未来、参与辩论以及遵守数学证明。

因为“慢”系统会有更多的精神消耗,我们会默认使用“快”系统 — 甚至在处理诸如编码这样的智力任务时。

想象一下你现在正陷于大量的任务中,你想快速的搞清楚下面的方法在做什么:

  1. function duplicateSpreadsheet(original) {
  2. if (original.hasPendingChanges) {
  3. throw new Error('You need to save the file before you can duplicate it.');
  4. }
  5. let copy = {
  6. created: Date.now(),
  7. author: original.author,
  8. cells: original.cells,
  9. metadata: original.metadata,
  10. };
  11. copy.metadata.title = 'Copy of ' + original.metadata.title;
  12. return copy;
  13. }

你也许会注意到这些:

  • 这个方法拷贝了一个表格
  • 如果表格没有被保存则抛出一个错误
  • 在新的表格标题上前置了“Copy of”

你也许没有注意到的是(如果注意到了更好)这个方法同时改变了原始的表格数据。

错过这样的bug可能会发生在每个开发者身上。但是现在你知道了有个bug的存在,你会以怎样的方式来阅读这段代码呢?如果你正在以“快”模式来阅读,那么你会切换到更为费力的“慢”模式来找到这个bug。

在“快”模式中,我们通过命名、注释和结构来猜测代码的含义。但是在“慢”模式下,我们需要一步一步的查看代码。

这就是具有一个正确的心智模型的重要性。在脑海里模拟计算机是很难的事情 — 何况这种努力还被错误的心智模型给浪费了。