前言
JS作为一门高级编程语言,其初衷是为了更加简便的去编写网页,而今天我就要来讲讲它能够让页面编写更加简单的一个秘密:包装类。
基本概念
在JS的世界里,几乎一切皆为对象——从基本的数据类型到复杂的函数、数组乃至自定义类,都能作为对象来处理和操作。而创建一个对象也很简单,直接
var obj = {}
即可,这就是JS,一门表现力极强的语言。
还有,对象中的key只能是字符串类型,但在JS的es6版本后,Symbol类型也可作为对象的key,我们暂且按下不谈。
那么再来了解一下对象上的增删改查
增
可以直接为对象新加入一个key,再将它赋值为value
obj.name = 'ace'
这样我们就为obj这个对象加了一个键为name,值为‘ace’的
还可将key作为变量传入对象并把变量的值作为key进行属性增加
var name = 'age'
obj[name] = 12
删
JS提供了delete关键字,可以删除对象中的属性
delete obj.age
效果如下
成功删除,delete操作会返回true;如果属性不存在或无法删除(比如尝试删除不可配置的属性),则返回false
改
修改对象中属性的值,可以通过点符号完成:
obj.name = 'Bob'; // 将obj的name属性值从'ace'修改为'Bob'
这段代码会将obj对象中name属性的值改为'Bob'。
使用方括号记法也可以达到修改属性值的目的,特别适用于动态属性名的情况:
obj[key] = 18;
如果key变量存储的是'age',那么这条语句会将obj对象中age属性的值修改为18。
查
直接控制台查询对象的键即可
下面进入正题
包装类
JavaScript中的包装类是一种机制,它允许原始数据类型(如字符串、数字和布尔值)像对象一样操作,拥有方法和属性。JavaScript的原始数据类型本身并不是对象,但为了方便操作,当尝试访问这些原始类型上的属性或方法时,JavaScript会临时创建一个包装对象,执行完操作后,这个临时对象会被销毁。JavaScript为三种基本类型提供了对应的包装对象:String、Number和Boolean。
String
对于字符串,当尝试访问字符串上的属性或方法时,JavaScript会创建一个String对象的实例。例如,调用toUpperCase()方法时:
let str = "hello";
let upperStr = str.toUpperCase(); // 这里会创建一个临时的String对象来调用toUpperCase方法
Number
对于数字,Number对象用于包装一个原始数值,提供了一系列与数值操作相关的属性和方法,如toFixed():
let num = 123.456;
let fixedNum = num.toFixed(2); // 创建临时的Number对象来调用toFixed方法
Boolean
布尔值也有对应的包装类Boolean,尽管不常用,但依然提供了如valueOf()方法来获取原始布尔值:
let bool = true;
let boolObj = new Boolean(bool); // 显式创建Boolean对象
console.log(boolObj.valueOf()); // 输出: true
注意事项
- 包装对象是动态创建和销毁的,一般不需要手动创建。
- 尽管可以使用
new String(),new Number(),new Boolean()构造函数显式创建包装对象的实例,但这在实际编程中并不常见,因为直接操作原始类型通常更高效且不易出错。 - 包装对象是不可变的,意味着一旦创建,其原始值就不能更改。
包装类的主要目的是为了在原始数据类型上提供面向对象的接口,使得可以调用方法来处理这些数据,而不必将其转换为完全的对象实例。这种机制体现了JavaScript的设计哲学,即在保持轻量级的同时,提供灵活的编程能力。
总结
在V8引擎中,对于原始值的包装类处理遵循了一套高效的机制来确保语言的一致性和性能。当V8遇到需要将原始值(如字符串、数字、布尔值)当作对象来操作的情景时,它会瞬时创建相应的包装对象(String、Number、Boolean)。这一过程确保了即使像原始值这样的简单数据类型也能临时获得方法调用的能力,例如字符串的.length访问或数字的.toFixed()方法。
然而,为了维持JavaScript中原始值的纯粹性——即它们本质上不拥有属性和方法的这一基本原则,V8在执行上下文中对这些包装类施加了特别的处理规则。具体而言,每当引擎检测到对包装类的使用完毕,或在确定操作可以安全地在原始值层面执行时,它会通过调用valueOf()方法来验证该包装对象是否代表一个原始值。一旦确认,V8不仅会移除由包装类添加的任何临时属性和方法,还会优雅地“卸下”包装,还原为原始值形态,从而避免了不必要的内存占用和潜在的逻辑混淆,保证了执行环境的整洁和高效。这一机制体现了V8对JavaScript语言特性的深刻理解与优化,确保了即便在复杂的异步执行环境中,原始值与包装类的交互也能保持清晰和高效。