JS中的拆箱和装箱

JS | 装箱和拆箱
谈谈JavaScript中装箱和拆箱

🫣 总结

  • 包装类与原始值转换过程叫做「装箱」和「拆箱」,装箱是将值类型包装为对象类型,拆箱是将对象类型转换为类型。
  • 装箱和拆箱是 JS 来应对「在值类型数据上调用对象方法」的处理技术,使得基础类型与相应的对象类型被统一。
  • 至于为什么要装箱和拆箱,个人理解:从内存使用的角度来看,是为了更好的性能。值类型存在栈里,引用类型存在堆里,在使用值类型的时候从栈里取的速度快,且大部分时候不需要调用对象类型中的方法,调用的时候用包装类型包装一下,调用完删除。

以下部分为摘录:

🛎️ 面向对象的妥协​

JavaScript中存在两套类型系统,其一是基础类型系统(Basetypes),是由typeof运算来检测的;其二是对象类型系统(Objecttypes),对象类型系统是 object 中的一个分支。

image.png

面向对象的语言通常认为“一切都是对象”。于是在“对象类型系统”中就出现了一个问题:如果是这样,那么number基础类型与Number对象类型,以及其他基础类型与相应的对象类型是如何被统一的呢?

为了实现“一切都是对象”的目标,JavaScript在类型系统上做出了一些妥协,

其结果是∶ 为部分基础类型系统中的“值类型”设定对应的包装类,通过包装类,将“值类型数据”作为对象来处理

image.png

这样一来,基础类型数据通过包装类转换而来的结果,和对象类型系统中的每一个实例一样,都成了理论上的“对象”。

  • typeof obj 的值为 object 或 function
  • obj instanceof Object 的值为 true

所以在值类型数据经过 “包装类” 包装后得到的是对象和原来的值类型数据不再是同一数据,只是二者同等的价值而已。

📫 显式装箱

  • 显式创建,通过基本包装类型对象对基本类型进行显示装箱。

例如:new Number(3) // Number{3}

从语言的实现来说,这与传统语言中的“类型强制转换”完全不同:强制转换是在同一数据(相同内存地址的不同引用)的基础上进行的,但上述语法将创建一个新的数据。

尽管值类型中的“符号类型(symbol)”存在对应的包装类,但是它不能通过这种显式创建的语法来得到对象实例。

  • 显式装箱,JavaScript内建的 Object() 类支持显式地将 boolean、number、string 和 symbol 四种值类型数据包装成对应的对象,这一语法在语义上解释为「基于值来创建等同的对象」。

例如:new Object(3) // Number{3}

装箱可以对new出来的对象进行属性和方法的添加,因为通过new操作符创建的引用类型的实例,在执行离开当前作用域之前一直保留在内存中。

📪 隐式装箱

对于隐式装箱,我们看下下面的代码:

var s1 = 'call_me_R'; // 隐式装箱
var s2 = s1.substring(2);

上面代码的执行步骤其实是这样的:

  1. 创建String类型的一个实例;
  2. 在实例中调用制定的方法;
  3. 销毁这个实例。

上面的三个步骤转换为代码,如下:

# 1
var s1 = new String('call_me_R');
# 2
var s2 = s1.substring(2);
# 3
s1 = null;

隐式装箱当读取一个基本类型值时,后台会创建一个该基本类型所对应的基本包装类型对象。在这个基本类型的对象上调用方法,其实就是在这个基本类型对象上调用方法。这个基本类型的对象是临时的,它只存在于方法调用那一行代码执行的瞬间,执行方法后立即被销毁。这也是在基本类型上添加属性和方法会不识别或

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值