探究v8中的包装类

对象

在 JavaScript 中,对象是一种复杂的数据类型 ,用于存储具有相关属性和方法的数据结构 。对象是基于键值对 的集合,其中键是字符串 (或者符号 Symbol),值可以是任何数据类型,包括函数,这些函数被称为对象的方法。

对象中属性的增加

我们先来看如下代码;

可以看到,我们用mrPeng.like = '章若楠'往对象mrPeng中添加了一个keylike,值为 '章若楠' 的属性;

但如果我们要是写成这样呢?

我们先定义了一个字符串abclike,再通过mrPeng.abc = '刘亦菲'往对象中添加属性,此时添加属性的key是什么呢?

可以看到,新增属性的key就为abc;并没有引用定义的字符串abc的值。这是因为在对象中,key只能是字符串类型 ;所以用.abc添加属性的方法就把abc当作字符串 传给了key

那可不可以把abc当成变量传给key呢?可以,只不过要换一种方式;

mrPeng[abc] = '刘亦菲',这是js中的一种语法,也可以往对象之中添加属性,[]允许使用变量作为属性名称

与传统方法不同的是,它把abc当作变量并找到它的值传给了key

对象中属性的删除

js中提供了delete的语法,用于删除对象中的属性;

可以看到,sex属性就被删除了。

对象的创建

创建对象字面量

在js中,最简单的创建对象的方法,那就是直接创建一个对象字面量;再给它添加上需要的属性和方法。

csharp 复制代码
// 创建对象字面量

var obj = {}

new Object()

除了对象字面量之外,我们还可以通过 Object()构造方法去实例化一个空对象

new XXX() 自定义的构造函数

再就是,我们可以自定义构造函数 ,用new方式去实例化一个对象:

实例化出来的对象如下:

new

在上篇文章中,我们已经介绍过new的过程了;在这里,我们还可以用另外一种更加通俗的方式来理解new的过程;

kotlin 复制代码
function Car(color) {
    this.name = 'su7'
    this.height = 1400
    this.lang = 5000
    this.weight = 1000
    this.color = color
}

// new 过程

// 先创建this空对象
var this = {}

// 执行函数中的代码,往this对象中添加属性
    this.name = 'su7'
    this.height = 1400
    this.lang = 5000
    this.weight = 1000
    this.color = color
    
// 返回this对象
return this

由于this指向的就是实例化的对象 ,故而我们可以直接把this当成实例化的对象;再向其中添加属性。

不通过new 实例对象

如果我们不使用new方法去实例化对象,那我们可以把new的过程直接写在构造函数里面;

在上面的这种形式中,也能够实例化一个对象。

包装类

在JavaScript中,包装类(Wrapper Classes)是一组特殊的构造函数 ,它们能够将基本数据类型(primitive types)封装成对象 。这样做的主要目的是为了让基本类型的值能够拥有属性和方法 。JavaScript提供了三个内置的包装类,分别对应三种基本数据类型:Number, String, 和 Boolean

原始数据类型

在js中,原始数据类型 (也称为基本数据类型或简单数据类型)是不可变的数据类型;主要分为以下几种:Number,String,Boolean,undefined,null,Symbol 和 BigInt;我们知道,原始值身上是不能有属性和方法的,属性和方法只有对象才能拥有。但是看着如下一段代码,你陷入了沉思;

str明明是字符串类型,那它怎么还能调用方法呢?实则不然,在原始数据类型中,Number,String 和 Boolean 都有内置的构造函数。

原始类型的内置方法

在js中,一切皆可看作对象 ;其实原始数据类型也是由它们自身内置的构造函数new出来的对象,如下图;

用上述方式构造出来的对象就是包装对象 ;这些包装对象具有与它们所封装的基本类型相对应的属性和方法 ,比如,字符串string能够调用.length方法去获取字符串的长度。

原始值上挂载属性

因为Number原始值我们可以把它看成是一个包装对象 ,当我们往原始值上挂载一个属性时,会发生什么呢?

在上面中,我们就往num上面挂载了一个len属性为3,但是打印的时候,输出了undefined

这是因为在JavaScript中,当你尝试在一个原始值上添加属性时,实际上是在创建并操作一个临时的包装对象 。但是,这种添加的属性不会持久存在,一旦操作完成,这个临时的包装对象就会被销毁,所以你添加的属性似乎"消失"了。这是因为原始值本身不支持属性的挂载

valueOf 返回对象的"原始值"

在JavaScript中,valueOf 方法是一个内置的方法,几乎所有的对象都有这个方法。valueOf 的主要作用是返回对象的"原始值" 。这个方法通常用于将对象转换为其代表的原始数据类型 ,尤其是当对象被设计为封装某种基本数据类型的时候

ini 复制代码
var str = 'abc' // new String('abc')
str += 1 // str = 'abc1'
var test = typeof(str) // 'string'
if (test.length === 6) {
    test.sign = 'typeOf的返回结果可能是String'
    // new String(test).sign = 'xxxx'
    // valueOf(test)  判断是否为原始值类型
    // delete test.sign
}
console.log(test.sign); // new String(test).sign  undefined

每当你往原始值身上挂载属性时,包装对象的valueOf内置方法就会返回它的原始值;如果是原始类型,v8引擎会把原始值身上添加的属性给delete移除掉;因为在v8看来,原始值是不能拥有属性和方法的。

小结

在原始值对象中,当v8执行到包装类时,会通过valueOf方法试探该包装类是不是原始值 ,如果是,则秉承原始值不用具有属性和方法的 这一规则,再移除掉给包装类添加的属性

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax