likes
comments
collection
share

“披着羊皮的狼” ---- Js包装类详解

作者站长头像
站长
· 阅读数 56

你是否还记得在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);

“披着羊皮的狼” ---- Js包装类详解

  • 但是!当我们往对象字面量上重复上面的操作时,就出现了不一样的结果。
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);

“披着羊皮的狼” ---- Js包装类详解 到这里,你似乎感觉到了直接创建的对象字面量,似乎不能再上面添加其他属性,但是同样都称为对象,为何偏偏它不行呢?

  • valueof() 方法

valueOf()方法是JavaScript中所有对象都继承的一个方法,它返回对象的原始值或者对象的字符串表示形式,具体取决于对象的类型。对于原始数据类型(如numberstringboolean)的包装对象,valueOf()方法返回的就是对应的原始值。

三、包装类

JavaScript中的包装类是三个特殊的类:StringNumberBoolean,它们分别用于封装基本数据类型stringnumberboolean,使其能够像对象一样操作。通过这些包装类,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
评论
请登录