美文网首页
Javascript基础之-强制类型转换(一)

Javascript基础之-强制类型转换(一)

作者: 小辞_8ae8 | 来源:发表于2018-12-29 21:15 被阅读0次

    转换为字符串规则如下图代码:

    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-international.org/ecma-262/5.1/#sec-9.8.1

    请思考下面的代码

    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/

    相关文章

      网友评论

          本文标题:Javascript基础之-强制类型转换(一)

          本文链接:https://www.haomeiwen.com/subject/qjtmlqtx.html