探究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方法试探该包装类是不是原始值 ,如果是,则秉承原始值不用具有属性和方法的 这一规则,再移除掉给包装类添加的属性

相关推荐
WeiXiao_Hyy23 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡39 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js