V8引擎类型转换(VIP课程)

简介: V8引擎类型转换(VIP课程)

这一章是源于一道面试题 完成以下条件并且输出console

if(a == 1 && a == 2 && a == 3) {
    console.log(true)
}

好家伙 乍一看一个变量怎么可能等于三个值?带着疑问我们去深入了解

类型系统

在JavaScript中类型系统不同于别的语言,例如JavaScript 执行一个表达式 '1' + 2等于多少?

  • python

在python中不允许字符串和数字相加的,因为python虚拟机觉得这是一个无意义的操作。

  • javaScript

不过在 JavaScript 中执行这段表达式,是可以返回一个结果的,最终返回的结果是字符 串“12”

V8 是怎么执行加法操作的?

  1. 将第一个表达式的值赋给左引用(lref)。
  2. 使用 GetValue(lref) 获取左引用的计算结果,并将其赋值给左值(lval)。
  3. 如果出现错误,使用 ReturnIfAbrupt(lval) 返回错误。如果没有错误,则执行以下步骤:
    a. 将左值(lval)转换为字符串并将结果赋给左字符串(lstr)。
    b. 将右值(rval)转换为字符串并将结果赋给右字符串(rstr)。
    c. 返回左字符串(lstr)和右字符串(rstr)拼接的结果。

接下来,描述了对第二个表达式的处理:

4. 将第二个表达式的值赋给右引用(rref)。

5. 使用 GetValue(rref) 获取右引用的计算结果,并将其赋值给右值(rval)。

6. 如果出现错误,使用 ReturnIfAbrupt(rval) 返回错误。如果没有错误,则执行以下步骤:

7. 使用 ToPrimitive(lval) 获取左值(lval)的计算结果,并将其赋值给左原生值(lprim)。

8. 使用 ToPrimitive(rval) 获取右值(rval)的计算结果,并将其赋值给右原生值(rprim)。

最后,根据左原生值和右原生值的类型进行不同的操作:

9. 如果左原生值(lprim)和右原生值(rprim)中至少有一个是字符串类型,则执行以下步骤:

10. 将左原生值(lprim)转换为数字并将结果赋给左数字(lnum)。

11. 将右原生值(rprim)转换为数字并将结果赋给右数字(rnum)。

12. 返回左数字(lnum)和右数字(rnum)相加的结果。

大概意思就是 V8引擎会提供一个 ToPrimitve 方法 用于获取原始类型 进行强制转换

具体转换的规则如下:

  1. 如果该值已经是原始数据类型(string、number、boolean),则直接返回该值。
  2. 如果其中一项是字符串,那另一项值就会转换成对应的字符串类型。
  3. 如果该值是对象(Object),则调用该对象的 valueOf() 方法,如果返回的结果是原始数据类型,则直接返回该值。
  4. 如果 valueOf() 方法的返回结果不是原始数据类型,则调用该对象的 toString() 方法,如果返回的结果是原始数据类型,则直接返回该值。
  5. 如果 toString() 方法的返回结果不是原始数据类型,则抛出 TypeError 异常。

看第二条 如果其中一项是字符串另一项值也就是number会进行隐式转换

'1' + Number(2).toString()

数组跟对象也是一样的会调用 valueOf 或 toString 看第四条

let a = '1'
let b = {name:1}
console.log(a + b) //1[object Object]
let a = '1,'
let b = [2,3,4]
console.log(a + b)//1,2,3,4

面试题

我们已经熟知底层原理,就可以做这个面试题了。

当对象参与相等(==)比较时,JavaScript 会尝试将对象转换为原始数据类型。而在这个过程中,JavaScript 会调用对象的 valueOf() 方法的返回结果不是原始数据类型,则调用该对象的 toString() 方法,如果返回的结果是原始数据类型,则直接返回该值

const a = {
    current:1,
    valueOf () {
        return this.current++;
    }
}
if(a == 1 && a == 2 && a == 3) {
    console.log(true)
}

思考题 请问答案是什么 可以发到评论区

const a = {
    valueOf () {
        return 100
    },
    toString () {
        return '200'
    }
}
console.log(a + 3)
目录
相关文章
|
6月前
|
SQL Oracle 关系型数据库
实时计算 Flink版产品使用合集之使用JDBC方式读取Oracle的number类型时,通过什么方式进行映射
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
153 0
实时计算 Flink版产品使用合集之使用JDBC方式读取Oracle的number类型时,通过什么方式进行映射
|
6月前
|
存储 索引
V8引擎如何存储对象(VIP课程)
V8引擎如何存储对象(VIP课程)
52 0
|
6月前
|
存储 JavaScript 前端开发
V8引擎隐藏类(VIP课程)
V8引擎隐藏类(VIP课程)
68 0
|
存储 关系型数据库 Java
IP地址处理攻略:数据库中的存储与转换方法
IP地址处理攻略:数据库中的存储与转换方法
361 0
|
存储 SQL NoSQL
MySQL数据库的数据类型和基于MySQL数据类型的综合实例项目(下)
MySQL数据库的数据类型和基于MySQL数据类型的综合实例项目(下)
MySQL数据库的数据类型和基于MySQL数据类型的综合实例项目(下)
|
存储 SQL 关系型数据库
史上最简单的 MySQL 教程(十一)「列类型 之 字符串型」
史上最简单的 MySQL 教程(十一)「列类型 之 字符串型」
82 0
|
SQL 存储 自然语言处理
OushuDB 用户指南类型转换之概述
OushuDB 用户指南类型转换之概述
55 0
实战:第五章:EZDML修改数据类型
实战:第五章:EZDML修改数据类型
123 0
实战:第五章:EZDML修改数据类型
|
JSON 分布式计算 数据处理
IP 转换_框架设计 | 学习笔记
快速学习IP 转换_框架设计
113 0
IP 转换_框架设计 | 学习笔记
|
缓存 分布式计算 关系型数据库
IP 转换_功能实现 | 学习笔记
快速学习IP 转换_功能实现
130 0
IP 转换_功能实现 | 学习笔记