是翻译的订阅邮件,非原创,下方有英文原文。
看一下这段代码:
let a = 10;
let b = a;
a = 0;
运行后a和b的值是多少?在进一步阅读之前,先理解它。
如果你已经写了一段时间的js,你可能会存疑:“我每天写的代码比这有难度多了,重点是啥?”
本练习的目的不是要想你介绍这些变量,相反,假设你已经十分熟悉这些,本练习的目的是为了然你构建起相应的心智模型。
再次阅读上面的代码,确定一下结果。(稍后将解释为什么这个意图如此重要)
当你第二次读它,请一步步密切注意你脑海中发生的事。你可能会有这样的思路:
let a = 10; //声明了一个变量a,设置(set)值为10;
let b = a; //声明变量b,设置(set)值为a的值。a的值是10,那么b也就是10;
a = 0; //将变量a的值改为0
//所以,现在a等于0,b等于10,这就是答案。
也许你的思路有些不同,也许你会说是分配(assign)而不是设置(set),或者说你的阅读顺序略有不同,也可能你得到了不同的结果。关注这些不同点,请注意,即使是独白,也无法捕捉到你的脑袋里到底发生了什么事,你可能会说将b的值设置为a,但是设置变量到底意味着什么呢?
你可能会发现,你熟悉的这些基础编程概念(如变量)和一些行为(如赋值),都有与之关联的一系列根深蒂固的类推。其中一些可能来自于现实世界,其他的一些可能会在你学习的其他领域中运用,利用数学中的数字。这些类推可能会重叠甚至矛盾,但是他们仍然可以帮你了解代码中正发生的事。
举个栗子,很多人第一次学习变量的时候把它作为一个可以填充的盒子。即使你在看到变量时不再想象成盒子,他们在你的想象中仍然可能表现为盒子的行为。这些关于你脑袋中的运作方式的的“近似”称为心智模型。如果你已经写了很长时间的代码,想要注意到这个可能会比较难,但请注意你的思维模式,他们可能是视觉、空间和机械惯性思维的结合。
这些直觉(如盒子状的变量)会影响我们一生的阅读代码的方式,但是有时,我们的心智模型是有问题的。可能我们早期阅读的教程为了简化说明而牺牲了准确性,可能我们早期学了其他语言,但错误的转移来了一些这个语言的特定属性。可能我们是从一些代码片段中推测出了一个心智模型,但从没有真的验证过其准确性。
发现和解决这些问题就是[Just JavaScript]的目的。我们会逐步的去构建(或者是重构)你的JavaScript心智模型,以使其更准确并且更实用。一个好的心智模型,会帮你更快的发现和解决bug们,会帮你更好的理解他人写的代码,也可以让你对自己的代码更有信心。
(最后说下,a的值是0,b的值是10,此为上述问题的答案。)
丹尼尔·卡尼曼(Daniel Kahneman)的《思考,快和慢》是一本广受欢迎的非小说类书籍。它的中心论点是,人类在思考时会使用两个不同“系统”。
只要有可能,我们就会依靠“快”系统。我们与许多动物都共享这个系统,这给了我们惊人的权限,如走路时不会跌倒。这种“快速”系统擅长模式匹配(生存必须)和“胆量反应”。但它并不擅长计划。
独特的是,由于额叶(大脑的某个部分)的发展,人类也慢慢拥有了“缓慢的”思维系统。这种“慢”系统负责复杂的逐步推理。它让我们能计划未来事件,并可以辩论或进行数学论证。
因为使用“慢”系统会消耗大量心神,所以在我们进行编码之类的智力任务时,我们会默认倾向“快速”系统去解决。
想象一下,你有好多工作,而你想快点完成的情况下,快速浏览下面这些:
function duplicateSpreadsheet(original) {
if (original.hasPendingChanges) {
throw new Error('You need to save the file before you can duplicate it.');
}
let copy = {
created: Date.now(),
author: original.author,
cells: original.cells,
metadata: original.metadata,
};
copy.metadata.title = 'Copy of ' + original.metadata.title;
return copy;
}
你可能注意到:
这个函数能复制一个电子表格
如果没有保存原始表格则会抛出错误
将副本添加到新的电子表格的标题上
你可能没注意到(如果注意到的话,那真是优秀了)该功能还意外更改了原始电子表格的标题。
像这样的bug每天都在每个码农身上发生,但是,既然知道存在这样一个bug,你将以不同方式阅读代码吗?如果你之前在“快速”模式下读代码,则可能会切换到更费力的“慢速”模式下进行查找。
在“快速“模式下,我们根据命名、注释和整体结构来猜测代码的作用。在慢速模式下,我们一步步追溯代码的作用。
这就是为什么拥有正确的心智模型如此重要,在我们脑子里形成一台虚拟电脑已经很难了,错误的心智模型会导致你浪费这些努力。
如果你没发现这个bug,也不要担心。这意味着你将充分利用本课程哦。在接下来的模块中,我们将一起重建JavaScript心智模型,让你可以随时发现这种bug。
以下是英文原文
*Read this code:
let a = 10;
let b = a;
a = 0;
What are the values of a and b after it runs? Work it out in your head before reading further.
If you’ve been writing JavaScript for a while, you might object: “This snippet is much simpler than the code I’m writing every day. What’s the point?”
The goal of this exercise isn’t to introduce you to variables. We assume you’re already familiar with them. Instead, it is to make you notice and reflect on your mental model.
What’s a Mental Model?
Read the code above again with an intention to really be sure what the result is. (We’ll see why this intention is important a bit later.)
While you’re reading it for the second time, pay close attention to what’s happening in your head, step by step. You might notice a monologue like this:
let a = 10;
Declare a variable called a. Set it to 10.
let b = a;
Declare a variable called b. Set it to a.
Wait, what’s a again? Ah, it was 10. So b is 10 too.
a = 0;
Set the a variable to 0.
So a is 0 now, and b is 10. That’s our answer.
Maybe your monologue is a bit different. Maybe you say “assign” instead of “set”, or maybe you read it in a slightly different order. Maybe you arrived at a different result. Pay attention to how exactly it was different. Note how even this monologue doesn’t capture what’s really happening in your head. You might say “set b to a”, but what does it even mean to set a variable?
You might find that for every familiar fundamental programming concept (like a variable) and operations on it (like setting its value), there is a set of deep-rooted analogies that you associated with it. Some of them may come from the real world. Others may be repurposed from other fields you learned first, like numbers from math. These analogies might overlap and even contradict each other, but they still help you make sense of what’s happening in the code.
For example, many people first learned about variables as “boxes” into which you can put stuff. Even if you don’t vividly imagine boxes anymore when you see a variable, they might still behave “boxy” in your imagination. These approximations of how something works in your head are known as “mental models”. It may be hard if you’ve been programming for a long time, but try to notice and introspect your mental models. They’re probably a combination of visual, spatial, and mechanical mental shortcuts.
These intuitions (like “boxiness” of variables) influence how we read code our whole lives. But sometimes, our mental models are wrong. Maybe a tutorial we read early on has sacrificed correctness for the ease of explaining. Maybe we incorrectly transferred an intuition about a particular language feature, like this, from another language we learned earlier. Maybe we inferred a mental model from some piece of code and never really verified if it was accurate.
Identifying and fixing these problems is what Just JavaScript is all about. We will gradually build (or, possibly, rebuild) your mental model of JavaScript to be accurate and useful. A good mental model will help you find and fix bugs faster, understand other people’s code better, and feel confident in the code you write.
(By the way, a being 0 and b being 10 is the correct answer.)
Coding, Fast and Slow
“Thinking, Fast and Slow” by Daniel Kahneman is a widely popular non-fiction book. Its central thesis is that humans use two different “systems” when thinking.
Whenever we can, we rely on the “fast” system. We share this system with many animals, and that gives us amazing powers like walking without falling all the time. This “fast” system is good at pattern matching (necessary for survival!) and “gut reactions”. But it’s not good at planning.
Uniquely, thanks to the development of frontal lobe, humans also possess a “slow” thinking system. This “slow” system is responsible for complex step-by-step reasoning. It lets us plan future events, engage in arguments, or follow mathematical proofs.
Because using the “slow” system is so mentally draining, we tend to default to the “fast” one — even when dealing with intellectual tasks like coding.
Imagine that you’re in the middle of a lot of work, and you want to quickly identify what this function does. Take a quick look at it:
function duplicateSpreadsheet(original) {
if (original.hasPendingChanges) {
throw new Error('You need to save the file before you can duplicate it.');
}
let copy = {
created: Date.now(),
author: original.author,
cells: original.cells,
metadata: original.metadata,
};
copy.metadata.title = 'Copy of ' + original.metadata.title;
return copy;
}
You’ve probably noticed that:
This function duplicates a spreadsheet.
It throws an error if the original spreadsheet isn’t saved.
It prepends “Copy of” to the new spreadsheet’s title.
What you might not have noticed (great job if you did though!) is that this function also accidentally changes the title of the original spreadsheet.
Missing bugs like this is something that happens to every programmer, every day. But now that you know a bug exists, will you read the code differently? If you’ve been reading code in the “fast” mode, it’s likely you’ll switch to the more laborious “slow” mode to find it.
In the “fast” mode, we guess what the code does based on naming, comments, and its overall structure. In the “slow” mode, we retrace what the code does step by step.
That’s why having a correct mental model is so important. Simulating a computer in our heads is hard enough — and this effort is wasted with wrong mental models.
Don’t worry if you can’t find the bug at all. This means you’ll get the most out of this course! Over the next modules, we’ll rebuild our mental model of JavaScript together so that you see this bug plain as day.
In the next module, we’ll start building mental models for some of the most fundamental JavaScript concepts — values and variables.*