JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?

简介: JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?

前言

JavaScript中类型转换是一个很令人头疼的问题,特别是对于初学者来说。这是由于 JavaScript 是一种弱类型语言,它在运行时会尝试自动转换数据类型,以使表达式能够执行。这种灵活性使得 JavaScript 非常强大,但也容易引发一些不直观的行为。就比如当字符串与数字相加时,例如"3" + 2,JavaScript 将数字 2 隐式转换为字符串,而不是执行数学运算。今天我们就来聊聊JS中的类型转换规则,并且带你解决经典面试问题[ ] == ![ ] ?。

在前面三篇文章中,我们详细的介绍了原始数据类型之间的互相转换,以及对象类型转原始数据类型,接下来我们来聊聊什么时候会用到类型转换以及这道面试题该怎么解

首先我们先来看两道例题,我们将对象转换为原始数据类型,运用我们上篇所讲知识,看看会输出什么:

console.log(Number({}));  // NaN
console.log(Number([]));  // 0
  • 首先我们先来看看将空对象{}转化为Number型的,我们可以看到答案为NaN,我们来分析一下,我们在对对象进行类型转换时,JS引擎会进行两个操作,ToPrimitive({}, Number),第一步,我们先来看看{}是不是基本类型,很显然不是,它是一个对象数据类型;接下来,我们调用valueof方法,我们知道valueof只能将包装类转换为它们对应的原始值,{}也不是包装类,所以我们不能得到原始值。接下来我们进行第三步,调用toString方法,{}空对象调用toString方法得到'[object Object]',得到一个字符串类型的原始值。第一个操作结束
  • 接下来进行第二个操作,将得到的原始值转化为对应的Number类型的值,因为原始值为'[object Object]',所以转化为数字类型时得到NaN
  • 接下来我们来看看将空数组[]转化为Number型的,我们知道数组也是对象,这里得到的答案为0,首先引擎先进行第一个操作,ToPrimitive([], Number),第一步,我们先来看看[]是不是基本类型,很显然不是,它是一个对象数据类型;接下来,我们调用valueof方法,我们知道valueof只能将包装类转换为它们对应的原始值,[]也不是包装类,所以我们不能得到原始值。接下来我们进行第三步,调用toString方法,[]空数组调用toString方法得到'',空字符串是一个字符串的原始值。第一个操作结束
  • 我们进行第二个操作,将得到的原始值''转化为对应的Number类型的值,所以空字符串在转化后得到0

一元运算符 +

在JavaScript中,一元运算符+可以用于将值转换为数字类型。这个操作符会尝试将其后面的操作数转换为一个数字。我们来看几个例子:

console.log(+'1') // 相当于Number('1')   输出 1

+号后面跟一个东西时,JS引擎会将它转换为Number类型,所以将字符串'1'转化为数字1, 所以输出1.

console.log(+[])    // 0

这里就相当于我们上面所讲的,+[ ] 相当于 Number([]),先调用ToPrimitive([], Number),得到原始值'',最后得到0

console.log(+ {})   // NaN

这里就相当于我们上面所讲的,+{} 相当于 Number({}),先调用ToPrimitive({}, Number){}空对象调用toString方法得到'[object Object]',得到一个字符串类型的原始值。接下来进行数字类型转换,得到NaN,所以最后输出NaN

console.log(+ [1, 2, 3]) // NaN

console.log(+ [1, 2, 3])相当于Number(+ [1, 2, 3]),先调用ToPrimitive(obj, Number),因为不是包装类,调用valueof并不能得到原始值,所以调用toString方法,得到'1,2,3'字符串,然后将字符串转化为Number类型,最后得到NaN

二元运算符 +

lprim + rprim == Toprimitive(v1) + Toprimitive(v2)

1. 转换之后当+两边有一个是字符串, 则按字符串进行拼接

2. 否则, 转到 number 进行计算

Toprimitive(v1),v1为原始数据类型时,那么直接返回该值

例如:

console.log(1 + '1');  // '11'

Toprimitive(v1) + Toprimitive(v2)之后,得到1 +'1',发现 +号两边有一边为字符串类型,那么则进行字符串拼接看i,先将1转为为字符串类型得到'1',最后拼接得到'11'

console.log(1 + null);  // 1

Toprimitive(v1) + Toprimitive(v2)之后,得到1 + null,发现两边没有任何字符串,则转换到数字类型Number进行计算,将null转换为Number,得到0,所以最后输出 1 + 0 = 1

console.log([] + []);  // ""

Toprimitive(v1) + Toprimitive(v2)之后,得到'' + '',发现两边都为字符串,则将两个空字符串进行拼接,最后得到''

console.log([] + {});  // '[object Object]'

Toprimitive(v1) + Toprimitive(v2)之后,得到'' + '[object Object]',发现+号两边都为字符串,所以将它们两个进行拼接,最后得到'[object Object]'

经典面试题

[ ] == ![ ] ?

在JavaScript中,[ ] == ![ ] 表达式的结果是 true让我们解释一下:

  1. [ ] 是一个数组,它被视为一个对象。当使用相等运算符(==)比较两个对象时,JavaScript 将尝试将它们转换为相同的类型。
  2. ![ ] 中的 ! 是逻辑非运算符,它将数组 [ ] 转换为布尔值并取其相反值。由于数组被视为一个真值,![ ] 将为 false
  3. 然后,比较 == 进行的是类型转换后的值。在比较对象时,JavaScript 会尝试将它们转换为原始值。对于数组,转换后的原始值是一个空字符串。

因此,实际上,表达式 [ ] == ![ ] 转化为 "" == false,之后会将它们转化为Number类型,也就是0 == 0,因此整个表达式的结果是 true

我们来看看伪代码:

[] == ![]     true
 [] == !true
 [] == false
 '' == 0
 0 == 0

总结

一元运算符+

在JavaScript中,一元运算符+可以用于将值转换为数字类型。这个操作符会尝试将其后面的操作数转换为一个数字。

二元运算符+

lprim + rprim == Toprimitive(v1) + Toprimitive(v2)

1. 转换之后当+两边有一个是字符串, 则按字符串进行拼接

2. 否则, 转到 number 进行计算

相关文章
|
1月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
40 3
|
1月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
2月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
57 3
|
4天前
|
JavaScript 前端开发 安全
如何处理 JavaScript 中的类型转换错误?
【10月更文挑战第9天】处理类型转换错误需要综合运用多种方法和策略,同时要保持对潜在问题的警惕性。通过合理的错误处理,可以提高程序的健壮性,减少因类型转换错误带来的负面影响。
9 0
|
4天前
|
JavaScript 前端开发
JS隐式类型转换规则
【10月更文挑战第9天】 不同的 JavaScript 引擎可能在隐式类型转换的具体实现上存在一些细微差别。理解这些隐式类型转换规则对于正确处理数据和避免错误非常重要。
13 0
|
5天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
2月前
|
数据采集 JavaScript 前端开发
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
爬虫技术是数据采集的关键手段。针对动态加载的网页,传统HTTP请求及HTML解析难以满足需求。本文章介绍如何利用ClearScript V8库在.NET环境中执行复杂的JavaScript逻辑,以提高爬虫对动态内容的抓取效率。文章首先概述了ClearScript V8的功能,如何处理如微博这类含有大量动态加载内容的网站。通过使用代理IP、设置cookie和user-agent等方式模拟真实用户访问,确保了爬虫的稳定性和隐蔽性。提供了一个具体的C#爬虫示例,演示如何结合ClearScript V8和HTTP客户端来实现上述功能。这种方法不仅增强爬虫的灵活性,也极大地提高数据采集的效率和可靠性。
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
|
1月前
|
JavaScript 前端开发
JavaScript 类型转换
JavaScript 类型转换
23 4
|
2月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
35 0
|
2月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码