从一道面试题入手,浅析JavaScript包装对象

我们先来看一道面试题:

一个字符串ss,typeof 'ss' 是String,但是它为什么会有.slice等方法。它不是一个对象,为什么会有方法?

这道面试题本质上问的就是:
按原始类型与引用类型的定义,只有引用类型才有属性和方法,而原始类型是没有自己的属性和方法的,那为什么字符串ss可以调用方法呢?是不是原始类型也能调用方法?

答案是否定的。原因就是我们今天要聊一聊的JavaScript包装对象了

JavaScript包装对象

JavaScript有三种原始类型的值——数值、字符串、布尔值。在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”。

所谓“包装对象”,指的是与数值、字符串、布尔值分别相对应的Number、String、Boolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

我们通过例子来理解一下:

var str = "hello" //包装对象String
var num = 100 //包装对象Number
var bool = true //包装对象Boolean

str.toString() //"hello"
num.toString() //"100"
bool.toString() //"true"

在调用toString时,JavaScript 引擎会自动将其转为包装对象,在这个对象上调用toString。调用结束后,这个临时对象就会被销毁。调用其他方法,如.length、.slice等。
这就叫原始类型与实例对象的自动转换。

而如果不是这三种包装对象呢?情况如下:

var und = undefined; //无包装对象
var nu = null; //无包装对象

und.toString(); //报错
nu.toString(); //报错

可以看到,如果不是包装对象,就不会实现原始类型与实例对象的自动转换。

而自动转换成包装对象是临时的,完成方法调用后就会被销毁,所以你无法在上面添加属性:

var str = "hello";
str.name = "test";
str.name //undefined

因为在第二行调用name赋值后,这个对象就被销毁了,第三行调用的是一个新的name,新的name并没有被赋值,所以是undefined。

包装对象自定义方法

包装对象可以自定义方法,供原始类型的值直接调用。比如,我们可以新增一个double方法,使得数字翻倍。

Number.prototype.double = function () {
  return this.valueOf() + this.valueOf();
};

(123).double() //246

总结

1、原始类型本身不能调用方法
2、原始类型在调用方法时,会生成包装对象,实现原始类型与实例对象的自动转换
3、当完成调用后,生成的临时对象会被销毁,所以原始类型本质是没有属性和方法的。
4、包装对象可以自定义方法供原始类型的值直接调用

如果您觉得我的文章有用,欢迎点赞和关注,也欢迎光临我的个人博客https://github.com/BokFang

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容