“披着羊皮的狼” ---- Js包装类详解
你是否还记得在Java、C++或者其他类似的编程语言中,定义一个变量常常要明确它的数据类型:int age = 23、String name = 'Tom'、blooean isStudent = true......,而在Js中,你只需要var、let、const加上变量名,附上变量值(=)就可以完成定义变量并且同时确定了它是什么类型的数据。
一、对象的几种表现形式
- 对象字面量
let obj = {}
- 原始值
let a = 5
let str = 'asd'
let bool = true
分别创建了数字字面量、字符串字面量、布尔字面量...... 也叫它们为原始值。
- new 的方式调用构造函数 new Object()
let obj = new Objcet()
let num = new Number()
let str = new String()
...
分别创建了对象obj、数值对象num、字符串对象str......
- new 的方式调用自己定义的构造函数
function Person(name,age){
this.name = name
this.age = age
}
let p = new Person('彭于晏',18)
二、往对象上添加属性
- 当我们往Person对象上添加属性 sex(性别)时,听起来和操作起来也是非常合情合理的。
function Person(name,age){
this.name = name
this.age = age
}
let p = new Person('彭于晏',18)
p.sex = 'man'
console.log(p.sex); //输出man
- 当我们往字符串str上添加sex属性,似乎听起来有点别扭,但是操作起来还是十分正常的。
var str = new String('aaa')
str.sex = '我是字符串,没有sex'
console.log(str.sex);
- 但是!当我们往对象字面量上重复上面的操作时,就出现了不一样的结果。
var str = 'aaa'
str.sex = '我是字符串,没有sex'
var num = 123
num.sex = '我是数值,没有sex'
var bool = true
bool.sex = '我是布尔,没有sex'
console.log(str.sex);
console.log(num.sex);
console.log(bool.sex);
到这里,你似乎感觉到了直接创建的对象字面量,似乎不能再上面添加其他属性,但是同样都称为对象,为何偏偏它不行呢?
- valueof() 方法
valueOf()
方法是JavaScript中所有对象都继承的一个方法,它返回对象的原始值或者对象的字符串表示形式,具体取决于对象的类型。对于原始数据类型(如number
、string
、boolean
)的包装对象,valueOf()
方法返回的就是对应的原始值。
三、包装类
JavaScript中的包装类是三个特殊的类:String
、Number
和Boolean
,它们分别用于封装基本数据类型string
、number
和boolean
,使其能够像对象一样操作。通过这些包装类,JavaScript的基本类型值可以获得额外的方法和属性,支持面向对象的编程风格。
- 原始值与包装类
1、当你直接用let、const、var
定义一个变量时,这个变量称为原始值,v8会将它进行“自动装箱”,将其自动转化为包装类。
var str = 'aaa' //v8相当于 new String("aaa")
str.sex = '我是字符串,没有sex'
var num = 123 //v8相当于new Number(123)
num.sex = '我是数值,没有sex'
var bool = true // v8相当于new Boolean(true)
bool.sex = '我是布尔,没有sex'
2、用new的方式调用构造函数,返回的对象就是一个包装类实例
var str = new String()
var num = new Number()
var bool = new Boolean()
当v8遇到往这两种包装类上添加属性时,会使用valueOf
方法,来检测一下它们是原始值“自动装箱”成的包装类,还是手动实例化(new)的包装类,如果是第一种的话,v8会直接delete掉该属性,而后者能添加上这个属性,这样就解决了创建对象字面量(原始值)时,不能访问到添加在上面的属性。
总结
包装类就是用于将基本类型(原始值)转化为对象,指的是三种构造函数String、Number、Boolean
,让基本类型值能够使用对象的方法,但是当没有以new的形式调用这些构造函数(包装类)时,v8会识别并且删除往它身上添加的其他属性,但是它们还是能访问到构造函数上Prototype的属性的。
转载自:https://juejin.cn/post/7379856289487159330