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

相关推荐
学地理的小胖砸1 小时前
【GEE的Python API】
大数据·开发语言·前端·python·遥感·地图学·地理信息科学
垦利不1 小时前
css总结
前端·css·html
八月的雨季 最後的冰吻2 小时前
C--字符串函数处理总结
c语言·前端·算法
6230_2 小时前
关于HTTP通讯流程知识点补充—常见状态码及常见请求方式
前端·javascript·网络·网络协议·学习·http·html
pan_junbiao3 小时前
Vue组件:使用$emit()方法监听子组件事件
前端·javascript·vue.js
hummhumm3 小时前
数据库系统 第46节 数据库版本控制
java·javascript·数据库·python·sql·json·database
正在绘制中4 小时前
如何部署Vue+Springboot项目
前端·vue.js·spring boot
Keep striving4 小时前
SpringMVC基于注解使用:国际化
java·前端·spring·servlet·tomcat·maven
Loong_DQX4 小时前
【前端】vue+html+js 实现table表格展示,以及分页按钮添加
前端·javascript·vue.js
伏城之外5 小时前
LeetCode - 15 三数之和
java·javascript·c++·python·leetcode·c