首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-05 23:46
  • 4310
  • 9892
juejin.cn

前言

在JavaScript的广阔天地里,类型转换是一个既基础又深奥的课题。它如同一位默默无闻的幕后工作者,悄然影响着代码的执行流程和结果。无论是初学者还是资深开发者,都难免会在与类型转换的交锋中遇到困惑和挑战。但正是这份复杂性,赋予了JavaScript灵活而强大的表达能力。本文旨在深入剖析JavaScript的类型转换机制,揭示其背后的原理和规则。通过理解和掌握这些类型转换的奥秘,我们将能够编写出更加准确、高效和健壮的代码,从而在JavaScript的编程之路上迈出更加坚实的步伐。

==vs===

js
代码解读
复制代码
console.log('1'==1); console.log('1'===1);

看一下这两行代码,猜一猜它的执行结果

87.png

可以看到这两个代码执行结果是不相等的

所以我们要知道===; 叫全等,不会进行隐式类型转换,意味着会判断值和类型是否相等,==;会进行隐式类型转换,所有只会判断值是否相等

类型转换

我们来看看下面这道大厂面试题

js
代码解读
复制代码
console.log([]==[]); console.log([]==![]);

判断这两段代码的输出结果,第一个我们都知道引用类型比较的是地址值,而不存在两个地址值完全相等的对象,因此第一行代码输出的肯定是false,那为什么加个!就相等了呢,我们都知道!在js中只是一个相反符号,这能有什么作用呢,其中就涉及到了类型转换,而面试官想问的就是你对类型转换的理解。读完这篇文章,你就能对类型转换有一个很深的理解了

原始类型之间的转换

我们先来想一下什么样子的代码进行与原始类型之间的转换,比如刚刚那==就是,还有就是字符串和数字的相加

js
代码解读
复制代码
1 + '1'=='11'

像这行代码,它会先把数字1转换为字符串'1',然后再拿两个字符串相加,就得到了'11',

js
代码解读
复制代码
'1' + true = '1true'

那字符串加布尔类型呢,要知道相加肯定要先转换为同一类型,布尔和布尔肯定是不能相加的,那会都转换为数字吗,也不是,布尔类型会先转换为字符串,然后再和字符串相加

我们知道一共有七种原始类型(Number,String,Boolean,bigInt,undifined,Null,Symbol()),而后面四种都不会有其它类型转为它们的情况,所以原始类型转换只有三种情况,转布尔,转字符串,转数字。

转布尔

js
代码解读
复制代码
console.log(Boolean(true)); console.log(Boolean(undefined)); console.log(Boolean(null)); console.log(Boolean(-100)); console.log(Boolean(0)); console.log(Boolean(NaN)); console.log(Boolean('hello')); console.log(Boolean(''));

我们将各种类型转为布尔看看都会转换为什么

88.png 可以看到布尔转布尔就是相当于没转,而有效数字转为布尔都为true,0为false,NaN为false,有字符的字符串转为布尔为true,空字符串为false,null和undefined为false。这些就是转为布尔的全部规则了

转数字

js
代码解读
复制代码
console.log(Number(1)); console.log(Number('0')); console.log(Number(undefined)); console.log(Number(null)); console.log(Number('hello'));

我们看看其它类型转数字是怎么样的

89.png 如果传入的是一个数字,其实它是不会转换的,而是将数字直接输出,如果是数字字符串,那么就会转换为对应的数字,undefined会转为NaN,而null会转换为0,如果是一个字符串,那么就不知道转换为什么数字,于是就会转换为未知数字NaN。

转字符串

原始类型转字符串是最简单粗暴的,就是用一对引号引起来。

对象转为原始值

对象转换为字符串

js
代码解读
复制代码
let a ={} console.log(String(a));

我们将对象转换为字符串是怎么样的,看看输出结果

90.png 为什么是这样的呢,其实在将对象转换为字符串的时候,v8引擎会先调用ToString方法,解决不了,然后就会使用ToPrimitive()方法,然后使用对象的toString方法转换为字符串。然后对象转字符串的方法在Object上,这是toString()方法执行的官方文档

84.png 这个文档表示的是当 Object.pritotype.toString.call()被执行的时候会干的几步操作,如果是undefined的话,那就直接返回[object Undefined],如果是null,那就返回[object Null]。

其它的,设0为调用To0bject 的结果,将this 值作为参数传递ToObject(this) 设class为0的[[Class]]内部属性的值。[[Class]]是js内部的属性,只有v8能用,可以直接读取变量的类型,最后返回由“[object ”、class 和 “]” 三块拼接的结果。

91.png 那为什么数组转为字符串是这样的,我们看了官方文档,如果是用的Object上的toString方法,格式就绝对不是这样的。那到底是为什么呢,其实是在数组的构造函数上重写了这个方法,而在数组上的toString方法就会返回由数组中元素由逗号分隔的字符串。

92.png 除了对象和数组,其它引用类型用toString转换为字符串都是直接返回 xx 的字符串字面量。

对象转布尔

93.png 在官方文档上就一条,true,无论什么对象转为布尔都是true

对象转数字

方法Number(obj)

过程 :To Number({}) //ToPrimitive({})

转数字会调用To Number({}) ,然后调用然后对象不能直接转为数字,就会使用ToPrimitive({}),转为原始类型最后再通过原始类型转换又再次变为数字

ToPrimitive({})

ToPrimitive(obj,String)

-如果obj是原始类型,直接返回 -否则调用toString()方法,如果得到原始类型则返回 -否则调用valueOf()方法,如果得到原始类型则返回 -否则报错

ToPrimitive(obj,Number)

-如果obj是原始类型,直接返回 -否则调用valueOf()方法,如果得到原始类型则返回 -否则调用toString()方法,如果得到原始类型则返回 -否则报错

隐式类型转换场景

1.四则运算:+ - * / %

2.判断语句 if while == > < >= <= !=

一元运算符 +

转数字类型

二元运算符 +

val1 + val2

lprim = ToPrimitive(val1)

rprim = ToPrimitive(val2)

如果 lprim或者rprim是字符串,另一个值直接被ToString()

  • 否则,都处理为数字,返回ToNumber(lprim) + ToNumber(rprim)应用加法运算的结果

==

如果类型相同,就比较值。 如果是null和undifined,那么返回true

其它的,如果是类型不同的比较,都是先转为数字再进行比较

最后我们再来看这道大厂面试题

js
代码解读
复制代码
console.log([]==[]); console.log([]==![]);

为什么加个!就是true了呢,我们来类型转换分析一下,首先由于前面加了一个!,那么就会使[]转换为布尔类型,前面我们提到过,所有引用类型转为布尔类型都会转为true,这是官方制定的规则,然后被!变为false,接下来就是两个不同类型用==进行比较了,那么我们就要先把它们转换为数字再比较,false转为数字就是0,而[]需要用toString转换为字符串,也就会变成空字符串'',然后再将字符串转为数字,空字符串转为数字就是0,最后v8就是将它们变成了0==0,当然返回的就是ture

看懂这些,那么你就已经掌握了js中类型转换这个知识点了。

结语

我们深入了解了JavaScript中的类型转换机制,学习了如何将原始类型和对象转换为字符串、数字和布尔值,并掌握了在特定场景下的类型转换规则。这不仅有助于我们更好地理解JavaScript的比较和运算行为,也为我们解决面试和实际开发中的类型转换问题提供了有力的武器。类型转换是JavaScript中的一个重要且复杂的概念,但通过不断学习和实践,我们可以逐渐掌握它,从而写出更加健壮和可靠的代码。

注:本文转载自juejin.cn的竺梓君的文章"https://juejin.cn/post/7444562650917961728"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

133
开发工具
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top