我们先来看一道面试题:
一个字符串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