ES 基础 —— 原始值的对象包装器

published

预备知识

原始值(Primitive Value)

来自 ECMA-262 中的定义:

Primitive Value:member of one of the types Undefined, Null, Boolean, Number, Symbol or String

对象包装器(Object Wrapper)

将原始值转化为对象,以使原始值获得对象才能拥有的能力。当前拥有对象包装器的基本数据类型有 Boolean,Number,String,Symbol。

对象包装器的执行过程

const s1 = 'some text'
const s2 = s1.substring(2)

上面的代码中,s1 包含一个字符串,字符串当然是原始值。而下一行却调用了 s1substring() 方法,并将返回值存储到了 s2 中。原始值不是对象,它们不该有方法。但,为什么能进行方法调用呢?

原来,在读取原始值时,引擎会:

  1. 为原始值创建对应的对象包装器。
  2. 在对象包装器上调用指定的方法。
  3. 销毁 1 中创建的对象。

可以将上面三个步骤想象成是执行了下列代码:

const s1 = 'some text'
let temp = new String(s1)
const s2 = temp.substring(2)
temp = null;

对象包装器的生存周期

对象包装器与常规对象的主要区别在于对象的生存期:

  • 自动创建的原始值的对象包装器,只存在于读取操作的瞬间,然后立即被销毁。
  • 使用 new 运算符创建的对象,在执行流离开当前作用域之前都一直保存在内存中。

这意味着我们不能在运行时为原始值添加属性和方法,比如:

const s1 = 'some text'
s1.color = 'red'
console.log(s1.color)  // undefined

上面的代码,为字符串 s1 添加一个 color 属性。但是,再次访问 s1 时, color 属性不见了。原因就是第二行代码创建的对象包装器在执行第三行代码前已经被销毁了,第三行代码又创建了另一个对象包装器,而此对象包装器没有 color 属性。