为什么JavaScript中的基本类型可以像对象那样调用方法

为什么JavaScript中的基本类型可以像对象那样调用方法

十一月 02, 2020

突然间心血来潮发现一个问题,在面向对象编程过程中,我们一般把业务中存在的一些事物抽象成代码中的对象,既有属性(保存值),也有方法(代表行为),继而通过对象的一系列组合调用完成业务调用。这是以前学习Java的时候学到的,在JavaScript一切皆对象,但是它也十分基本类型和引用类型的,基本类型在我看来就是一个值,没有任何方法,那它为什么能够调用方法呢?比如:

1
2
3
const str = 'Hello, world!'
const test = str.substring(0, 5)
console.log(test) // Hello

str是我们声明的一个基本类型变量,为什么它能够调用substring这个方法???

iShot2020-11-02 17.12.12

上面是我从Medium看到的一段解释:

The “object wrappers” are different for each primitive type and are called: String, Number, Boolean and Symbol. Thus, they provide different sets of methods.

理解下来就类似Java中的自动拆装箱一样,平时就是一个值,当你调用方法的时候Js引擎会用object wrappers将其包装成对应的对应类型,比如String,这样既保持了基本类型的轻量化,又可以使其继承一些公共方法进行调用。

代码中str调用方法时候的执行过程如下:

  1. The string str is a primitive. So in the moment of accessing its property, a special object is created that knows the value of the string, and has useful methods, like toUpperCase().
  2. That method runs and returns a new string (shown by log).
  3. The special object is destroyed, leaving the primitive str alone.

So primitives can provide methods, but they still remain lightweight.The JavaScript engine highly optimizes this process. It may even skip the creation of the extra object at all. But it must still adhere to the specification and behave as if it creates one.