我们会从一段代码片段开始这个模块。

  1. let reaction = 'yikes';
  2. reaction[0] = '1';
  3. console.log(reaction);

你期望它能做什么呢?我们还没有涵盖这个,如果你不知道的话也是可以的。尝试用你现有的 JavaScript 知识回答这个问题。

现在,我希望你能花一小部分时间将你的准确的思考过程写下来。注意现有心智模型里的不足的和不确定的地方,同时也把它们写下来。如果你有任何疑问,请尽可能清楚地表达出来。

答案是上述代码的运行不会输出 yikes,即时在严格模式下运行过程中也不会抛出任何错误。它最终将打印出 '1ikes'

哎呀。

原始值是不可变的

你回答正确了吗?这看起来是一个琐碎的问题,就像是面试中会遇到的但是实际又不会遇到的问题。尽管如此,这也回答了对于原始值来说很重要的一个点。

无法改变原始值。

我会通过一个小型示例来进行解释。字符串(是原始值)和数组(是对象)有一定相似的地方,数组是项的有序排列,字符串是字符的有序排列。

  1. let arr = [1, 2, 3];
  2. let str = 'hello';

访问数组中的第一个项和访问字符串中的第一个字符的方式很像,这使得字符串很像数组(实际上并不是):

  1. console.log(arr[0]); // 1
  2. console.log(str[0]); // h

你可以改变数组的首项:

  1. arr[0] = 4;
  2. console.log(arr); // [4, 2, 3];

用直觉来看的话,也可以让字符串做到同样的事情:

  1. str[0] = 'j';
  2. console.log(str); // ???

但是实际上是不能这么做的。

这里有个重要的点需要添加到我们的心智模型中。字符串是原始值,这意味着很多。

所有的原始值都是不可变的。不可变(Immutable)是拉丁文中无法改变的奇特的表达。只读。你无法混淆原始值。

如果你想在原始值上添加属性,无论是数字、字符串还是其他的,JavaScript是不会允许你这么做的。它会默默地拒绝或者抛出错误,这取决于你的代码运行在哪个模式下。

所以请放心下列代码永远不会正常工作:

  1. let fifty = 50;
  2. fifty.shades = 'gray';

就和其他数字一样,50 是原始值,你不能给它设置属性。

在我的JavaScript宇宙,所有的原始值都存在于距离我的代码很远的外圈中 — 像是遥远的星星。