JavaScript 数据类型之间的转换(显示转换 和 隐式转换)
数据类型的转换
强制转换
强制转换主要是指使用 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 数组或对象的扁平化处理
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论