likes
comments
collection
share

类型转换:编程中的桥梁与挑战

作者站长头像
站长
· 阅读数 27

导读

在编程的世界里,数据是沟通的基石,而类型则是数据的形态和规则。不同的场景和操作要求数据以特定的类型存在。因此,类型转换成为了编程中不可或缺的一环,它如同一座桥梁,连接着数据处理的不同需求,同时也考验着程序员对数据类型的深刻理解和灵活运用。本文将结合官方文档深入探讨类型转换的概念、重要性、常见方式以及潜在的风险与最佳实践。

什么是类型转换?

类型转换,简而言之,就是在程序运行过程中,将一种数据类型转换为另一种数据类型的过程。这可以是自动完成的(由编译器或解释器隐式执行),也可以是显式通过代码指定的。类型转换的需要源于多种情况,比如函数参数类型不匹配、运算符对操作数类型有特定要求,或是数据存储与展示格式的差异等。

常见的类型转换方式

常见类型转换有原始值转布尔 Boolean(xx)原始值转数字 Number(xx)原始值转字符串 String(xx)原始值转对象 new Xxx() 以及 对象转原始值。这些类型转换又可以分为显示类型转换隐式类型转换

显示类型转换:使用Boolean(xx)Number(xx)String(xx)以及new Xxx() 进行类型转换。

隐式类型转换:js执行引擎遵循一定的规则进行类型转换,这个过程你看不见。

其中重难点理解对象转原始值,由于其大部分是隐式转换,转换机制隐蔽,因此常常会出现一些令人难以理解的东西,如下:

都发生隐式转换

 + '123' ==> 123
 + [] ==> 0
 
 1 + '1' ==> '11'
 null + 1  ==> 1
 [] + {} ==> '[object Object]'
 
 1 == {}  // false
[] == ![]  // true

而这些又经常在面试时会遇到,要你讲清楚原理。

要理解这些东西,需要借助官方文档阅读,究其根本。

1. XXX 转换成 Number,String,Boolean以及对象的结果

XXX转换为Number转换为String转换为Boolean
false0"false"false
true1"true"true
00"0"false
11"1"true
"0"0"0"true
"1"1"1"true
NaNNaN"NaN"false
InfinityInfinity"Infinity"true
-Infinity-Infinity"-Infinity"true
""0""false
"20"20"20"true
"twenty"NaN"twenty"true
[ ]0""true
[20]20"20"true
[10,20]NaN"10,20"true
["twenty"]NaN"twenty"true
["ten","twenty"]NaN"ten,twenty"true
function(){}NaN"function(){}"true
{ }NaN"[object Object]"true
null0"null"false
undefinedNaN"undefined"false

原始值转对象大部分都是new Xxx(),例如:new String("hello"),这不是重点,就一笔带过。

2. 对象转原始值详解

对象一般都是转字符串,数字,布尔。不会有谁闲着没事干去转null和undefined,毕竟没啥意义。

对象转布尔都是true,记住就行。

官方文档:es5.github.io/#x15.5.1.1

我们在查阅官方文档时发现,当是对象转**原始值(字符串,数字)**时,会调用一个函数ToPrimitive(),接受一个参数,即表示期望的转换结果类型,可以是字符串或者数字。如下是转换为数字的例子:

类型转换:编程中的桥梁与挑战 是这么描述的:调用ToPrimitive()返回primValue值,再用ToNumber()primValue进行转换。

我们再来查看函数ToPrimitive()干了件什么事: 类型转换:编程中的桥梁与挑战 对于原始类型,直接返回,这个好理解。

重点看对象是什么转换逻辑,点击8.12.8详解:

类型转换:编程中的桥梁与挑战 类型转换:编程中的桥梁与挑战 步骤概括如下:

    1. 调用toString方法,如果得到原始值,返回
    1. 否则,调用valueOf方法,如果得到原始值,返回
    1. 报错

补充: toString方法和valueOf方法转换规则

    1. {}.toString() 得到由 "[object", class 和 “]”组成的字符串
    1. [].toString() 返回数组内部元素以逗号拼接的字符串
    1. xx.toString() 返回字符串字面量 类型转换:编程中的桥梁与挑战
  • valueOf方法仅用于包装类:

类型转换:编程中的桥梁与挑战

综上所述,我们可以把ToPrimitive()总结为以下步骤:

    1. 如果接收到的是原始值,直接返回值
    1. 否则,调用toString方法,如果得到原始值,返回
    1. 否则,调用valueOf方法,如果得到原始值,返回
    1. 报错

注意:注意如果是想把对象转化为数字则会先执行valueOf方法,反之,如果是想把对象转化为字符串则会先执行toString方法!

其最终是要把对象转成原始值。

运用类型转换解决疑难点

+ '123' ==> 123 
+ [] ==> 0 

1 + '1' ==> '11' 
null + 1 ==> 1 
[] + {} ==> '[object Object]' 

1 == {} // false 
[] == ![] // true

把这些问题归为三类:一元操作符二元操作符以及 “==”运算

对于一元操作符,官方文档如下描述

类型转换:编程中的桥梁与挑战

// + '123' ==> 123
// ToNumber('123')
// 123

// + [] ==> 0
// ToNumber([])
// ToPrimitive([], Number)
// [].valueOf()
// [].toString()  ====> ''
// ToNumber('')
// 0

对于二元操作符,官方文档如下描述

类型转换:编程中的桥梁与挑战

// 1 + '1' ==> '11'
// ToPrimitive(1)   +   ToPrimitive('1')
// 1  +  '1'
// ToString(1) + '1'
// '1' + '1'
// '11'


// null + 1
// ToPrimitive(null)   +   ToPrimitive(1)
// null + 1
// ToNumber(null) + ToNumber(1)
// 0 + 1
// 1

[] + {}
// oPrimitive([])   +   ToPrimitive({})
// [].valueOf() + {}.valueOf()
// [].toString() + {}.toString()
// '' + '[object Object]'
// '[object Object]'

对于“==”运算,官方文档如下描述类型转换:编程中的桥梁与挑战 找到对应的情况:

[] == ![]
// [] == false
// [] == 0
// ToPrimitive([]) == 0
// '' == 0
// 0 == 0
// true

类型转换的挑战与风险

  1. 数据丢失:尤其是在从高精度类型转换到低精度类型时,如浮点转整数。
  2. 异常与错误:不恰当的转换可能导致运行时错误,如空指针异常、类型不匹配异常。
  3. 性能开销:频繁或复杂的类型转换可能引入额外的计算成本,影响程序效率。
  4. 可读性与维护性:过度依赖类型转换可能会使代码逻辑变得复杂,不利于阅读和维护。

结语:

通过以上深入的探讨,我们已经详尽地解析了类型转换在编程世界中的核心概念、常见方式、以及背后复杂的逻辑,尤其是对象到原始值转换的详细机制。

写作不易,觉得写的好的话,给个赞,感谢!!!

转载自:https://juejin.cn/post/7370980422901284879
评论
请登录