JavaScript 数据类型之间的转换(显示转换 和 隐式转换)

发布于 2022-06-04 13:29:34 字数 9160 浏览 1049 评论 0

数据类型的转换

强制转换

强制转换主要是指使用 Number()、String() 和 Boolean() 三个构造函数,手动将各种类型的值,转换成 number、string 和 boolean。

1、Number() 可以将任意类型的值转化成数值。

// 数值:转换后还是原来的值 
Number(123); // => 123 

// 字符串:如果可以被解析为数值,则转换为相应的数值 
Number('123'); // => 123 

// 字符串:如果不可以被解析为数值,返回NaN 
Number('123abc'); // => NaN 

// 空字符串转换为0 
Number(''); // => 0 // 

布尔值:true转成1,false转成0 
Number(true); // => 1 
Number(false); // => 0 

// undefined: 转换成NaN 
Number(undefined); // => NaN 

// null: 转成0 
Number(null); // => 0 

// 对象:将返回NaN,除非是包含单个数值的数组 
Number({a: 1}); // => NaN 
Number([1, 2, 3]); // => NaN 
Number([1]); // => 1

除了 Number() 之外,还可以通过 parseInt() 和 parseFloat() 来转换

【不同】parseInt() 与 parseFloat() 只能在 String 类型上调用,而 Number() 不仅限于 String 类型,比如 Date 类型上也可以使用。

parseInt(string, radix)】: 首先查看位置 0 处的字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置 1 处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt()将把该字符之前的字符串转换成数字。

var iNum1 = parseInt("12345red");// => 12345 
var iNum1 = parseInt("0xA"); // => 10 
var iNum1 = parseInt("56.9"); // => 56 
var iNum1 = parseInt("red"); // => NaN

parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由parseInt()方法的第二个参数指定的。

[1,2,3,4].map(parseInt)结果是?

[1, NaN, NaN, NaN]

相当于

parseInt(1,0) //1
parseInt(2,1) //NaN 1为基数转换为NaN(进制规则)
parseInt(3,2) //NaN
parseInt(4,3) //NaN

参数radix: 转换所采用的基数,2到36之间。
解析规则: string参数被看做radix指定进制下的数要把它转换成十进制的整数。

没有指定基数/基数为0时

  • 参数string以“0x”或“0X”开头,radix取16;
  • 参数string以“0”开头,ECMAScript5规定radix只能取10,然而ECMAScript3允许- radix取8。具体的解析结果依然由实现环境而定。
  • 其他情况下,radix取10.

基数为1或大于36时:解析结果为NaN

基数处于2到36之间时

  • 如果string参数的第一个字符(除空白以外),不属于radix指定进制下的字符,解析结果为NaN;
  • 如果第一个字符属于radix指定进制下的字符,则解析到不属于radix指定进制下的字符时,将忽略该字符及其后的所有字符。
parseInt(2,4) //2
parseInt(2,3) //2
parseInt(2,2) //NaN
parseInt(5,3) //NaN

parseFloat(string)】:parseFloat()方法与parseInt()方法的处理方式相似,从位置 0 开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成整数。

不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。

该方法没有基数模式。

字符串必须以十进制形式表示浮点数,而不是用八进制或十六进制。该方法会忽略前导 0,所以八进制数 0102 将被解析为 102。对于十六进制数 0xA,该方法将返回 NaN,因为在浮点数中,x 不是有效字符。(注释:经测试,具体的浏览器实现会返回 0,而不是 NaN。)

var fNum1 = parseFloat("12345red");// => 12345 
var fNum2 = parseFloat("0xA"); // => NaN 
var fNum3 = parseFloat("11.2"); // => 11.2 
var fNum4 = parseFloat("11.22.33");// => 11.22 
var fNum5 = parseFloat("0102"); // => 102 
var fNum1 = parseFloat("red"); // => NaN

Number()】:Number()函数的强制类型转换与parseInt()和parseFloat()方法的处理方式相似,只是它转换的是整个值,而不是部分值

Number()属于强类型转换,使用强制类型转换可以访问特定的值,即使它是另一种类型。

parseInt()和parseFloat()方法只转换第一个无效字符之前的字符串,因此 “1.2.3” 将分别被转换为 “1” 和 “1.2”。

用Number()进行强制类型转换,”1.2.3″ 将返回 NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number()将判断是调用parseInt()方法还是parseFloat()方法。

var date = new Date('Tue Jun 14 2016 00:00:00'); 
console.log(Number(date));// => 1465833600000

Number(false); // => 0 
Number(true); // => 1 
Number(undefined); // => NaN 
Number(null); // => 0 
Number('1.2'); // => 1.2 
Number('12'); // => 12 
Number('1.2.3'); // => NaN 
Number(new Object({}));// => NaN 
Number(50);  // 50

2、使用String(),可以将任意类型的值转化成字符串。

// 数值: 转为相应的字符串 
String(123); // => '123' 

// 字符串: 转换后还是原来的值 
String('123'); // => '123' 

// 布尔值: true转为'true',false转为'false'
String(true); // => 'true' 
String(false); // => 'false' 

// undefined: 转为'undefined' 
String(undefined); // => 'undefined' 

// null: 转为'null' 
String(null); // => 'null' 

// 对象:返回一个类型字符串 
// 数组:返回该数组的字符串形式 
String({a: 1}); // => [object Object] 
String([1, 2, 3]); // => '1,2,3'

toString()String()】的主要区别就在于String()还能转换null和undefined值。

String(null); // 'null'
String(undefined); // 'undefined'
null.toString(); // 报错

// 但可以借用toString()
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"

new String()】转换出来的是一个object。而这个对象是一个对基本类型值str的包装器对象。

3、使用 Boolean(),可以将任意类型的变量转为布尔值。

它的转换规则相对简单:除了以下六个值的转换结果为false,其他的值全部为true。

Boolean(undefined); // => false 
Boolean(null); // => false 
Boolean(0); // => false 
Boolean(NaN); // => false 
Boolean(''); // => false

注意:所有对象,包括空对象的转换结果都是 true,甚至连 false 对应的布尔对象 new Boolean(false) 也是 true

Boolean({}); // => true 
Boolean([]); // => true 
Boolean(new Boolean(false)); // => true

所有对象的布尔值都是true,这是因为JavaScript语言设计的时候,出于性能的考虑,如果对象需要计算才能得到布尔值,对于obj1 && obj2这样的场景,可能会需要较多的计算。为了保证性能,就统一规定,对象的布尔值为true。

隐式类型转换

隐式转换是以强制转换为基础的。

多数情况下,在 JavaScript 中比如遇到 -、*、/ 和 % 等算术运算都会把操作数转换成数字的,但是 + 和其他的有点不一样,有些情况下,它是算术加号,有些情况下是字符串连接符,具体的看它的操作数。

// 不同类型的数据互相运算 
123 + 'abc'; // => '123abc' 

// 对非布尔值类型的数据求布尔值 
if ('abc') { 
	console.log('hello'); // => 'hello' 
} 

// 对非数值类型的数据使用一元素运算符即+和- 
+ {foo: 'bar'}; // => NaN 
- [1,2,3]; // => NaN

1. 字符串的隐式转换规则

123 + 'abc' // '123abc'
'abc' + 123 // 'abc123's
3 + '12' // '321'
'12' + 3 // '123'
true + '5' // 'true5'
'5' + true // '5true'
false + '5' // 'false5'
'5' + false // '5false'
'5' + function (){} // "5function (){}"
(function (){}) + '2' // 'function(){}2'
'5' + undefined // "5undefined"
undefined + '5' // 'undefined5'
'5' + null // "5null"
null + '5' // 'null5'
'5' + {} // "5[object Object]"
{} + '5' // 5 注意转换成数字了
'5' + [] // "5"
[] + '5' // '5'

字符串的自动转换,主要发生在加法运算时。会将非字符串的数据自动转为字符串。系统内部会自动调用 String() 函数。

2. 数字的隐式转换规则

'5' - '2' // 3 
'5' * '2' // 10 
true - 1 // 0 
false - 1 // -1 
'1' - 1 // 0 
'5' * [] // 0 
false / '5' // 0 
'abc' - 1 // NaN
{} - 1 // -1 注意和空对象进行算术运算(空对象在前) 无论是加法还是其他 会自动转换为数值
1 - {} // NaN

除了加法运算符有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。系统内部会自动调用Number()函数。

+'abc' // NaN 
-'abc' // NaN 
+true // 1
-false // 0

一元运算符也会把运算子转成数值。

3 + true; // 4
1 + 2 + '3'; // '33'

此外,需要注意的是,+的运算符方向是从左到右。


在 JavaScript 中,隐式类型思考换有时候会隐藏一些错误的,比如 null 会转换为 0,undefined 会转换成 NaN。需要注意的是:NaN 和 NaN 是不相等的

NaN === NaN // false

虽然在JavaScript中提供了isNaN来检测某个值是否为NaN,但是,这也不太精确的,在调用 isNaN 之前,本知就存在一个隐式转换的过程,它会把那些原本不是NaN的值转换为NaN。

isNaN('foo'); // => true 
isNaN(undefined); // => true 
isNaN({}); // => true 
isNaN({a:'xxx'}); // => true

3. 对象的隐式转换规则

// 对象可以转换成原始值的,把它转换成字符串 
'The Math Objec: ' + Math; // => 'The Math Object:' [object Math]' 
'The JSON Object:' + JSON; // => 'The JSON Object:' [object JSON]' 

// 对象转换成字符串 
Math.toString(); // => '[object Math]' 
JSON.toString(); // => '[object JSON]' 

// 对象可以转换成数字 
'J' + {toString: function (){ return 'S'}}; // => 'JS' 
2 * {valueOf: function() {return 3}}; // => 6

如果,一个对象同时存在 valueOf() 和 toString() 时,那么 valueOf() 总是会先被调用。

var obj = { 
	toString: function() { 
		return '[object MyObject]'; 
	}, 
	valueOf: function() { 
		return 1 
	} 
}; 
'Object: ' + obj; // => 'Object: 1'

但是,多数情况下,这都不是我们想要的,一般的,尽可能使 valueOf() 和 toString() 表示的值相同。

valueOf()toStringOf()

4. 布尔值的隐式转换规则

当 JavaScript 遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。系统内部会自动调用 Boolean()函数。

因此除了以下六个值,其他都是自动转为true。

  • undefined
  • null
  • -0
  • 0 或 +0
  • ' '
if ( !undefined 
	&& !null 
	&& !0 
	&& !NaN 
	&& !'' 
) { 
	console.log('true'); 
} // true

// 写法一 
expression ? true : false 

// 写法二 
!! expression

References

JavaScript 中数据类型转换

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文