奇怪的JavaScript类型转换(中)

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

接奇怪的js类型转换(上),聊一下显示强制类型转换和隐式强制类型转换。

显式强制类型转换

显式强制类型转换就是那些显而易见的类型转换,下面是常见的几种

string<->number

    // 一般转换
    var a = 24;
    var b = String(a); // '24'
    var e = a.toString(); // '24'
    
    var c = "3.14";
    var d = Number(c); // 3.14
    var f = +c; // 3.14
    
    // 日期显式转换为数字
    var timeInt = +new Date();
    var timeInt2 = new Date().getTime();
    
    // ~运算符
    var s = 'hello';
    ~a.indexOf('lo'); //true
    
    // 字位截除, ~~
    Math.floor(-82.7); // 83
    ~~82.7 //82
复制代码

当然,后面两个可读性并没有那么好。

显式解析数字字符串

    var a = '24';
    var b = '24px';
    Number(a); // 42
    parseInt(a); // 42
    Number(b); // NaN
    parseInt(b); // 42
复制代码

parseInt主要针对的字符串值,如果传递其他类型的参数是没有用的,例如true,function(){},[1,2,3]。parseInt接受第二个参数,用来指定转换基数,一般正常情况都是10进制,但是如果乱传会有意想不到的效果,比如

    parseInt(1 / 0, 19) // 这里输出的是18,
复制代码

这里看似不合理,其实js解析过程中会认为是parseInt(‘Infinity’, 19)。第一个字符是”I”,以19为基数时值为18,第二个字符”n”不是一个有效的数字字符,解析到此为止,和上面的”24px”中的”p”是一个意思。后面的19,也不会起作用,因为他的有效数字范围为0-9和a-i。除了这些还有一些看起来奇怪也解释的通的例子。

    console.log(parseInt(0.000008)); // 0
    console.log(parseInt(0.0000008)); // 8
    console.log(parseInt(false, 16)); // 250
    console.log(parseInt(parseInt, 16)); // 15
    console.log(parseInt('0x10')); // 16
    console.log(parseInt('103', 2)); //2
复制代码

显式转换为boolean

var a = '0';
var b = [];
var c = {};
var d = '';
var e = 0;
var f = null;
var g;
console.log(Boolean(a)); //true
console.log(Boolean(b)); //true
console.log(Boolean(c)); //true
console.log(Boolean(d)); //false
console.log(Boolean(e)); //false
console.log(Boolean(f)); //false
console.log(Boolean(g)); //false
复制代码

Boolean是显式的,但并不常用。最常用的方法是,!!,即

var a = '0';
var b = [];
var c = {};
var d = '';
var e = 0;
var f = null;
var g;
!!a,
!!b
// ...
复制代码

toBoolean另外一个用处,是在JSON序列化过程中将值强制类型转换为true或者false

var a = [
  1,
  function(){},
]
JSON.stringify(a); // "[1, null]"
JSON.stringify(a, function name(key, val) {
  if(typeof val == 'function') {
    return !!val;
  }else {
    return val;
  }
}); // "[1, true]"
复制代码

隐式强制类型转换

隐式强制类型转换指的是那些隐蔽的强制类型转换,副作用也不是很明显,换句话说,你觉的自己不够明显的强制类型转换都可以算作隐式强制类型转换。作用就是减少冗余,让代码更简洁。

string->number

    var a = "24";
    var b = "0";
    var c = 24;
    var d = 0;
    a + b // '240'
    c + d //24
    var a = [1,2];
    var b = [3,4];
    a + b; // "1,23,4"
    a + ''
复制代码

a + ”和前面的string(a)之间友谊个席位的差别,根据toPrimitive抽象操作规格,前者会调用valueOf方法,然后通过toString抽象操作将返回的值专为字符串,而后者直接调用toString。

||和&&

这两个运算符并不陌生,但是这两个返回值不一定都是布尔类型,而是两个操作数种的一个值。

24 || 'abc' // 24
24 && 'abc' // 'abc'
null || 24 // 24
null && 24 // null
复制代码

其实这两个运算符的原理大多数人都应该知道, ||有时候会做短路作用,即前面已经确定boolean值为真了,就直接返回前面一个,否则返回后面一个,而 && 是两个的boolean都为真,才会返回后面一个值,否值只能返回false。通常我们可用改操作去做值选择器或者为了简化三目运算符。

符号转换

这里有个不同的坑点,es6出来的Symbol类型

var s1 = Symbol('abc');
String(s1); // "Symbol(abc)"
var s2 = Symbol('abc');
s2 + ''; // TypeError
复制代码

符号不能够被强制类型转换为数字,但可以被强制类型转换为布尔值。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享