我们会从一段代码片段开始这个模块。
let reaction = 'yikes';
reaction[0] = '1';
console.log(reaction);
你期望它能做什么呢?我们还没有涵盖这个,如果你不知道的话也是可以的。尝试用你现有的 JavaScript 知识回答这个问题。
现在,我希望你能花一小部分时间将你的准确的思考过程写下来。注意现有心智模型里的不足的和不确定的地方,同时也把它们写下来。如果你有任何疑问,请尽可能清楚地表达出来。
答案是上述代码的运行不会输出 yikes
,即时在严格模式下运行过程中也不会抛出任何错误。它最终将打印出 '1ikes'
。
原始值是不可变的
你回答正确了吗?这看起来是一个琐碎的问题,就像是面试中会遇到的但是实际又不会遇到的问题。尽管如此,这也回答了对于原始值来说很重要的一个点。
无法改变原始值。
我会通过一个小型示例来进行解释。字符串(是原始值)和数组(是对象)有一定相似的地方,数组是项的有序排列,字符串是字符的有序排列。
let arr = [1, 2, 3];
let str = 'hello';
访问数组中的第一个项和访问字符串中的第一个字符的方式很像,这使得字符串很像数组(实际上并不是):
console.log(arr[0]); // 1
console.log(str[0]); // h
你可以改变数组的首项:
arr[0] = 4;
console.log(arr); // [4, 2, 3];
用直觉来看的话,也可以让字符串做到同样的事情:
str[0] = 'j';
console.log(str); // ???
但是实际上是不能这么做的。
这里有个重要的点需要添加到我们的心智模型中。字符串是原始值,这意味着很多。
所有的原始值都是不可变的。不可变(Immutable)是拉丁文中无法改变的奇特的表达。只读。你无法混淆原始值。
如果你想在原始值上添加属性,无论是数字、字符串还是其他的,JavaScript是不会允许你这么做的。它会默默地拒绝或者抛出错误,这取决于你的代码运行在哪个模式下。
所以请放心下列代码永远不会正常工作:
let fifty = 50;
fifty.shades = 'gray';
就和其他数字一样,50
是原始值,你不能给它设置属性。
在我的JavaScript宇宙,所有的原始值都存在于距离我的代码很远的外圈中 — 像是遥远的星星。