“ 最近在面试的时候,犯了一个低级的错误,是关于基本类型引用的问题,下面就让我们一起来分析一下流程是如何的。”
1 | Object.prototype.test = 'test test'; |
此时你是不是很好奇,基本类型还可以进行点(.)操作访问?
其实我在面试的时候也是犯了一个很低级的错误,然后不假思索的就答了一句:会报错的,那么恭喜你成功的跳进了坑里面,关键还乐开了花。
对于基本类型的值,它其实是不可变的,包括使用任何方法也都是无法改变基本类型的值。我们是不能给基本类型添加属性和方法的,即使添加了再去访问也是访问不到的。例子:
1 | // 任何方法都无法改变一个基本类型的值 |
在了解了上面基本类型是不可变的,并且是不能给基本类型添加属性和方法的。所以当我们再来看上面的代码。先拆分一下代码:
1 | // 首先它是不会报错的 |
接下来我们再来看看在对象原型链上添加test字段和值,在基本类型中能否访问到test字段的值呢?不卖关子了,答案是肯定的,它是能访问到并且在控制台中打印出’test test’值。
首先需要知道在JS中一切皆对象。对于基本类型的话,我们需要先了解包装对象。
在了解完上面的问题之后,现在再来一个问题的衍生:平时我们在定义基本类型boolean、string、number时,它们没有原型链可以提供方法,但是却可以调用toString等对象原型上的方法。
其实js引擎在解析上面语句时,会把这三种基本类型解析为包装对象。什么是包装对象呢?其实就是String、Number、Boolean。
1 | let str = 'hello world'; |
关于包装对象和引用类型区别:其实就是对象生存周期不同。包装类型只存在于一行代码的执行瞬间,当执行完毕立即被销毁;引用类型在当前作用域中都会保留。
结论:基本类型不是对象,但是如果使用基本类型变量可以调用方法或者访问字段值,那是因为临时产生的包装对象。
因此当我们访问test字段,其实就是访问Object对象原型上的test,它肯定是可以访问到的,因为JS中一切皆对象。其实最好的方法是大家可以看看下面这张网络上的原型链图片,图片如下所示:
原型链图
所以最后我们综合再来看看最后输出的答案是什么:
1 | Object.prototype.test = 'test test'; |
如果你认为这篇文章对你有帮助的话,不妨来一个三连啦。