转换为字符串规则如下图代码:
- 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/
来源: https://yq.aliyun.com/articles/685878