MENU

深入了解JavaScript类型转换:显式与隐式转换的区别与应用

• May 9, 2024 • JavaScript阅读设置

在 JavaScript 中,类型转化只能转化为三种基本类型。
z.webp.jpg

to string
to number
to boolean
to string
有两种方式可以转化为 string 类型。

toString()
String()
toString返回当前值的字符串的等价物。数值、布尔值以及字符串值都有 toString 方法,这个方法只是简单的返回自身的一个副本而已。 注意:null 和 undefined 是没有 toString 方法的。 大多数情况下,toString()不接受任何参数。不过在对数值调用这个方法时,接受一个底数参数,默认 toString 返回数值的十进制字符串,可以通过传入底数,得到二进制、八进制、十六进制或者其他任何有效的字符串。

const num = 10;
num.toString(); //'10'
num.toString(2); //'1010'
num.toString(8); //'12'
num.toString(10); //'10'
num.toString(16); //'a'
String函数始终返回表示相应类值的字符串。遵循以下规则转化:

如果值有toString方法,则调用该方法,不传入任何参数,并返回结果。
如果值是null,则返回'null'
如果值是undefined,则返回'undefined'
String(null); //'null'
let value;
String(value); //'undefined'
String(12); //'123'
String(true); //'true'
因为 null 和 undefined 没有 toString 方法,所以 String 直接返回这俩值的字面量文本

当遇到操作符+号,其中一个操作数为 string 类型,另一个操作数则会隐式转化为 string 类型。

String(1); //显式转换 '1'
String(1.2); //显式转换 '1.2'
String(null); //显式转换 'null'
String(undefined); //显式转换 'undefined'
String(true); //显式转换 'true'
String(false); //显式转换 'false'
1 + ''; //隐式转换 操作符+号 且其中一个操作数为string类型。结果'1'
to number
在 JavaScript 中有三个函数可以将非数值显式转化为数值:

Number()
parseInt()
parseFloat()
Number函数基于如下规则完成转化过程。

boolean类型,true为1 ,false转化为0。

数值,直接返回。

null,返回 0。

undefined,返回NaN。

字符串,应用以下规则:

如果字符串是数值或者前面带加减号的情况,则转化为一个十进制数值。

Number('123'); //123
Number('+123'); //123
Number('-123'); //-123
Number('123abc'); //NaN
Number('0012'); //12 忽略前面的0
如果字符串包含有效的浮点值如1.2,则会转化为相应的浮点值。(同样会忽略前面的 0)

如果字符串包含有十六进制格式如0xf,则会转化为与该十六进制对应的十进制整数值。

如果是空字符串,则返回0

如果字符串包含除了上述以外的其他字符,则返回NaN

parseInt函数更专注于字符串是否包含数值模式,字符串前面的空格会被忽略,从第一个非空格字符开始转化,如果第一个字符不是数值、+或者-号,则直接返回 NaN。(注意:空字符也会被转化为NaN)。如果第一个字符是数值、+或者-号,则依次检测每个字符,直到遇到非数值字符或者到字符末尾。

parseInt('123blue'); //123
parseInt(''); //NaN
parseInt('123.123'); //123
注意:parseInt 函数是能识别不同的整数格式,如十六进制或者八进制,也就是说如果是以0x开头,则会被解释为十六进制整数,如果以0开头,且紧跟着数值字符,则会被解释为八进制。但不同的数值格式其实很容易混淆,因此 parseInt 接受第二个参数,用于制定底数(也就是进制数),如果需要解析的值为十六进制,则第二个参数传入 16,以便正确解析。不传底数,就是 parseInt 自己决定如何解析。为了避免解析错误,建议带上第二个参数。

parseInt('010'); //10
parseInt('010', 8); //8 八进制
parseInt('0xA'); //10
parseInt('0xAF'); //175
parseInt('AF', 16); //175 如果传了进制数,则16进制可以省略前面的0x
parseInt('AF'); //NaN
parseFloat函数的工作方式和parseInt函数类似,都是从第一个字符开始检测,同样,也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。这意味着第一次出现的小数点是有效的,但第二次以及后面出出现的小数点则无效。此时后面的字符也会被忽略。但 parseFloat 和 parseInt 不同的点在于 parseFloat 始终忽略字符串开头的 0,parseFloat 不支持传入进制数,十六进制会解析成 0,因此 parseFloat 只解析十进制数值。

parseFloat('123blue'); //123
parseFloat('123.12.1'); //123.12
parseFloat('00123.12.1'); //123.13
parseFloat('0xA'); //0
parseFloat('3.125e7'); //31250000
隐式转化的情况有以下几种:

比较操作符(<,>,<=,>=)
按位操作符(| & ^ ~)
四则运算 (- + * / %) 其中操作符为+号,一方操作数为 string 类型,则隐式转化为 string 类型,。
一元操作符 (+)
loose equality operator == ,也包括!=
转化规则参考 Number 函数

注意:虽然Number(null)为 0,但null==0为 false,null==undefined为 true。NaN 不等于任何值,包括它自己。

to boolean
调用 Boolean 函数 显示转化为 boolean,或者遇到逻辑操作符(|| && !) 则会隐式转化为 boolean 类型。 除了以下几种情况转为 false,其他则为 true。

Boolean(''); // false
Boolean(0); // false
Boolean(-0); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean(false); // false
即使是[]或者{}对象,也会转化为 true

Boolean({}); // true
Boolean([]); // true
Boolean(function() {}); // true
对象转化为基本类型
Object 依然只能转化为 number、string 和 boolean 三种基本类型。

Object 转化为 boolean 最简单,永远为 true.即使为空对象或者空数组等。
Object 转化为 string 或者 number,通过调用一个内置方法[[ToPrimitive]]实现转化。代码如下:
function ToPrimitive(input, preferredType) {
switch (preferredType) {

case Number:
  return toNumber(input);
  break;
case String:
  return toString(input);
  break;
default:
  return toNumber(input);

}

function isPrimitive(value) {

return value !== Object(value);

}

function toString() {

if (isPrimitive(input.toString())) return input.toString();
if (isPrimitive(input.valueOf())) return input.valueOf();
throw new TypeError();

}

function toNumber() {

if (isPrimitive(input.valueOf())) return input.valueOf();
if (isPrimitive(input.toString())) return input.toString();
throw new TypeError();

}
}
一般来说,转化的过程如下:

input 为基本类型,啥也不做直接 return。
调用 input.toString(),结果为基本类型,return。
调用 input.valueOf(),结果为基本类型,return。
不满足以上三点则抛出 TypeError. 转化为 number,则先调用 valueOf(),再调用 toString();转化为 string,则正好相反,先 toString(),再 valueOf()。 不同操作符会触发不同转化规则,根据参数 preferredType 要么转化为 number 要么是 string。 注意:遇到==和+操作符,preferredType 未赋值或者等于默认值时,则默认转为 number,除了 Date。
var obj = {
prop: 101,
toString() {

return 'Prop: ' + this.prop;

},
valueOf() {

return this.prop;

},
};

console.log(String(obj)); // 'Prop: 101'
console.log(obj + ''); // '101'
console.log(+obj); // 101
console.log(obj > 100); // true

/* Date测试 /
let d = new Date();
let str = d.toString();
let num = d.valueOf();
console.log(d == str); //true
console.log(d == num); //false
以上就是【js类型转换】的全部内容了。