JS数据类型分类:
基本数据类型:Stiring、Number、Boolean、Undefined、Null、Symbol、BigInt(ES6新增)
引用数据类型:Object
在学习JavaScript时,我们是否会有一个疑问,在JS中不仅引用类型(如Object、Array等)有属性和方法,而且连基本类型(如string、number)也有属性和方法,这是怎么回事呢?
其实啊,JS为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
String()
- 可以基本数据类型字符串转换为String对象
Number()
- 可以基本数据类型数字转换为Number对象
Boolean()
- 可以基本数据类型布尔值转换为Boolean对象
var str = new String('hello') // str是一个值为'hello'的对象 即:String{'hello'}
var str1 = 'hello'
var num = new Number(3) // num是一个值为3的对象 即:String{'hello'}
var num1 = 3
var bool = new Boolean(true) // bool是一个值为true的对象 即:String{'hello'}
var bool2 = true
console.log(str) // String {'hello'}
console.log(num) // Number {3}
console.log(bool) // Boolean {true}
console.log(typeof str) // object
console.log(str === str1) // false (str是对象,而str1是字符串)
但是啊,我们在实际应用中不会使用基本数据类型的对象,
如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果
那么问题来了,既然实际开发中不用,JS为什么要提供这三个包装类呢?
在回答这个问题之前,我们先来了解了解为什么基本类型String、Number、Boolean也有属性和方法呢?
如字符串的 charAt() 方法
charAt 方法 接收一个参数,基于0的字符位置
charAt 方法 是以单字符串的形式返回给定位置的那个字符
var str = 'hello world'
console.log(str.charAt(1)) // e
这是为什么呢?好像有点有悖常理,那么现在我们就一探究竟,看看到底是怎么回事?
说回上面,JS为我们提供了三个包装类,但是实际开发中,我们又不会使用基本类型的对象。
其实,三个包装类的是给后台使用的,比如浏览器,当我们调用比如字符串的方法时,后台会临时通过包装类来创建对象,然后通过对象调用方法,完成之后就会立即销毁,
我们平常写程序的过程:
var str = 'sunwukong' // string 基本类型
var s2 = str.charAt(0)
console.log(s2) // s
console.log(str) // sunwukong
实际上在执行 var s2 = str.charAt(0) 这行代码时,后台做了很多工作:
JavaScript高级程序设计里是这样描述的:
1.创建 String 类的一个实例
2.在实例上调用指定的方法
3.销毁这个实例
代码说明如下:
var _str = new String('sunwukong') // 1.找到对应的包装类,然后通过包装类临时创建一个和基本类型值相同的对象
var s2 = _str.charAt(0) // 2.然后这个对象就可以调用包装对象下的方法,并且返回给 s2
_str = null // 3.最后自动销毁这个临时创建的对象
所以,此刻我们也就深度理解了为什么基本类型能够调用方法和属性了,原来都是后台在默默的工作,也明白了JS中包装类的作用了,就是提供给后台使用的
最后注意一点,
虽然后台会将通过包装类,将基本数据类型转换为实例对象,但是,由于它也会自动销毁该实例,所以我们不能对基本数据类型添加属性和方法,这也符合常理
如:
var dashixiong = 'sunwukong'
dashixiong.age = 18
console.log(dashixiong.age) // undefined
执行到第二行代码属性赋值时,后台通过包装类创建了一个实例,这个age属性确实挂到这个临时的实例上去了,但是紧跟着,这个实例就被销毁了,执行到第三行时,又通过包装类重新创建了一个新的实例,这个新实例是没有 age 属性的。