JS是弱类型语言,在使用不同类型的数据进行运算操作时,常常伴随着类型转换,有的是显式的类型转换,有的是隐式的类型转换。在之前的文章ECMAScript中的基本概念-数据类型-Number类型-数值转换 和 ECMAScript中的基本概念-数据类型-String类型-转换为字符串中讲了一些显式的数字和字符串的类型转换。常见的隐式的类型转换如下:
let a = 1;
let aa = '1';
let b = 2;
let bb = '2';
let c = 0;
let cc = '0';
let dd = '';
console.log(a + b); // number 3
console.log(a + bb); // string '12'
console.log(aa + b); // string '12'
console.log(aa + bb); // string '12'
console.log(a + dd); // string '1'
console.log(typeof +aa, +aa); // number 1
console.log(typeof +bb, +bb); // number 2
console.log(typeof +cc, +cc); // number 0
let date = new Date();
console.log(Object.prototype.toString.call(date)); // [object Date]
console.log(typeof date, date) // object 2021-08-16T07:54:31.341Z
console.log(typeof +date, +date) // number 1629100471341
数字加上一个字符串,数字会被转换成String类型。而把加运算符使用在一个字符串上会String类型转换成Number类型。在Date对象上使用加运算符会把Date对象转换成Number类型的时间戳。而!!是将表达式强制转化为Boolean类型,正如ECMAScript中的基本概念-数据类型-Boolean类型的例子列举。 ~~ 运算符的作用和Math.floor差不多,但操作更高效,对于正数是向下取整,对于负数是向上取整。同时~~ 运算符对于字符串会进行类型转换,对于包含字母的字符串,Math.floor返回NaN,而~~ 运算符返回0。
let num1 = 3.14;
let sNum1 = '3.14';
let num2 = -3.14;
let sNum2 = '-3.14';
let abc = 'abc';
let bcd = '123bcd';
console.log(Math.floor(num1), Math.floor(~~num2)); // 3 -3
console.log(~~num1, ~~num2); // 3 -3
console.log(typeof Math.floor(sNum1), typeof Math.floor(~~sNum2)); // number number
console.log(Math.floor(sNum1), Math.floor(~~sNum2)); // 3 -3
console.log(typeof ~~sNum1, typeof ~~sNum2); // number number
console.log(~~sNum1, ~~sNum2); // 3 -3
console.log(Math.floor(abc)); // NaN
console.log(~~abc); // 0
console.log(Math.floor(bcd)); // NaN
console.log(~~bcd); // 0