转换为字符串规则如下图代码:
console.log(String(undefined)); // “undefined”
console.log(String(null)); // “null”
console.log(String(true)); // “true”
console.log(String(+0)); // “0”
console.log(String(-0)); // “0”
console.log(String(-20)); // “-20”
console.log(String(Infinity)); // “Infinity”
console.log(String(new Number(123))) // 123
console.log(String(new Object())) // [object Object]
console.log(100000000000000000000000000000); // 1e+29
大致就是普通其他基本类型转为字符串的话,就直接转为其值的字符串表达形式,
如果是基本类型的封装对象,会先拆封,然后再转为字符串,
如果是普通对象,则会调用其内部 [class] 的值,
如果是极大数和级小数,将会进行一些转化,具体规则请参考 ecma 官方文档 https://www.ecma-internationa…
请思考下面的代码
var obj = {
toString() {
return “toString”;
}
}
console.log(String(obj)) // toString
var obj1 = Object.create(null);
obj1.valueOf = function() {
return “valueOf”;
}
console.log(String(obj1)); // valueOf
上面这个代码似乎可以看出,实际上普通对象转为字符串的过程,似乎就是 toString()的一个过程,也就是调用其内部 toString()的一个过程
如果 toString()没有咋办,调用 valueOf,如果这个也没有呢,就直接报错了。
转换为数字的规则
普通转换为数字的规则如下:
console.log(Number(true)); // 1
console.log(Number(0b1101)) // 13
console.log(Number(false)); // 0
console.log(Number(“123”)); //123
console.log(Number(“123a”)); //NaN
console.log(Number(undefined)); // NaN
console.log(Number(null)); // 0
不过呢,如果是对象类型的咋办呢,实际上同上的一点是,如果是基本类型封装后的对象,会先拆封,也就是转为基本类型值,然后再转为数字,比如说
console.log(Number(new String(“123123″))); // 123123
console.log(Number([1])); // 1
console.log(Number([1, 3])); // NaN
可能你会疑惑,说,为啥数组只有一个数据的时候可以转换,有两个数据的时候就是 NaN 了呢,原因在这里,看代码
console.log([1].valueOf()); // [1]
console.log([1, 3].valueOf()); // [1, 3]
console.log([1].toString()); // 1
console.log([1, 3].toString()); //1, 3
可以看到,valueOf 没有返回基本类型值,所以转而使用 toString 转为基本类型值,这俩字符串再转为数字的结果就一目了然了,和上面的是一样的
那么转为数字的过程中,valueOf 和 toString 是哪个先执行的呢?
看代码
var a = {
valueOf() {
return 2;
},
toString() {
return 3;
}
}
var b = {
valueOf() {
return [1, 3];
},
toString() {
return 3;
}
}
var c = {
toString() {
return 3;
}
}
var d = Object.create(null);
console.log(Number(a)); // 2
console.log(Number(b)); // 3
console.log(Number(c)); // 3
console.log(Number(d)); // Uncaught TypeError: Cannot convert object to primitive value
这个其实就说明了一个问题,就是说对象转数字的时候,会先找 valueOf(),如果 valueOf()没有,或者是说转的是非基本数据类型的,将会使用 toString(),最后基本类型专成数字类型的,如果 valueOf 和 toString()都没有,就直接报错了
转化为数字呢,除了以上使用 Number(),还可以使用 + 符号,这个也可以实现从其他类型转换到字符串
console.log(+”abc”); // NaN
console.log(+”1111″); //1111
console.log(+[1]); // 1
var obj = {
valueOf() {
return “1111”;
}
}
console.log(+obj); // 1111
如果原数据类型是 Date,那么可以用 Number 或者 + 转为以微秒为单位的 unix 时间戳
var d = new Date(“Mon, 18 Aug 2014 08:53:06 CDT”);
console.log(+d); // 1408369986000
console.log(Number(d)); //1408369986000
parseInt 和 Number()的区别:看例子
var a = “123abc”;
console.log(+a); // NaN
console.log(parseInt(a)); // 123
console.log(parseInt(“abc123”)); // NaN
实际上,parseInt 会从左往右进行解析,找到非字符串的时候停止,如果一开始就不可转为数字,那么就返回 NaN
parseInt 其他一些坑点,这里就不细说了,想看的,可以找《你不知道的 Javascript》了解细节
// 0 (“0” 来自于 “0.000008”)
console.log(parseInt( 0.000008));
// 8 (“8” 来自于 “8e-7”)
console.log(parseInt( 0.0000008));
// 250 (“fa” 来自于 “false”)
console.log(parseInt( false, 16));
// 15 (“f” 来自于 “function..”)
console.log(parseInt( parseInt, 16));
console.log(parseInt( “0x10”)); // 16
console.log(parseInt( “103”, 2)); // 2
转化为布尔值
下面是假值列表,理论上说,除了以下内容以外的值都是 true
console.log(Boolean(undefined));
console.log(Boolean(null));
console.log(Boolean(false));
console.log(Boolean(+0));
console.log(Boolean(-0));
console.log(Boolean(NaN));
console.log(Boolean(“”));
这里有一点需要说明,规范里有提到,所有的对象都是 true,所以这方面尤其需要注意的就是下面的例子了
console.log(Boolean(new Boolean(false))); // true
console.log(Boolean(new String(“”))); // true
console.log(Boolean(new Number(0))); // true
返回的都是 true,虽然他是对假值得封装,但是他们是对象,是对象就返回 true,所以用假值对象或者其他看起来像价值的字符串来进行 if 判断是不靠谱的
var bObj = new Boolean(false);
var a = [];
var d = {};
var e = function() {}
var f = “false”;
var g = “0”;
var h = “””;
if (a && d && e && f && g && h) {
console.log(‘all right’); // all right
}
一般显式的吧数据转为布尔型,除了使用 Boolean()以外,还可以使用!! 符号,也就是连着反转两次
console.log(!!undefined); // false
console.log(!!new Boolean(false)); // true
好了就到这里了,这一次因为东西比较零散,准备了一阵子,希望大家有所收获
参考书籍《你不知道的 Javascript 中卷》
本文转载自 http://www.lht.ren/article/5/