概念

这里我们首先需要知道什么是值类型转换

值类型转换:将值从一种类型转换为另一种类型,就是类型转换,分显示转换和隐式转换

js类型转换出的值都是基本类型(number、boolean、string、null、undefined、string),并不会转换为引用类型的值。

强制类型转换

类型转换发生在静态语言的编译阶段,强制类型转换则发生在动态语言的运行阶段,在js中通常把他们统称为强制类型转换,而强制类型转换可以分为两种,方便我们后面的理解,下面举出一些列子

显示强制类型转换
var  a = 42
var c =String(a)
隐式强制类型转换
var a = 42 
var c =a + ''

这里注意下一元操作符 + ,+ 只要左侧或右侧出现字符串类型的都会是字符串拼接,后续会细说

在了解细致的显示与隐式的强制类型转换之前,我们得先知道值类型转换的方式’

显示强制类型转换:数字、字符串、布尔之间的类型转换

为了将值转换为对于的基本类型的值,我们这里得先了解下ToPrimitive,该方法会通过内部操作DefaultValue,检查该值是否带有valueOf()方法,有就返回基本类型,就用该值作为强制类型转换,没有就用toString()得返回值(若存在)来进行强制类型转换

字符串

负责非字符串到字符串得强制类型转换,这里书上P44页只介绍了toString,为了更好的对非字符串转换为字符串的理解,举出下面的列子

额外介绍:在谷歌浏览器中,console.log打印出的数字是蓝色的字体,字符串是黑色的字体

1、String()

String()是js的全局函数可以把null、undefined转换为字符,但是没办法转换为进制字符串,其他的都和toString()一样,如下列子:

      var a = null;
      var b = undefined;

      console.log(String(a));
      console.log(String(b));

image-20211210164131639

2、toString()

toString()是object原型的一个方法,它与String的区别就是不能转换null、undefined,会报错,其他的没什么区别,如下列:

      var a = null;
      var b = undefined;
      console.log(a.toString());
      console.log(b.toString());

image-20211210164456007

3、JSON.stringify()

JSON.stringify()对象序列化转换为字符串的时候也调用了toString,的方法,这里值得注意的是,JSON.stringify(),并非严格意义上的强制类型转换用法与toString基本一致,但是也有区别,如下:

1、JSON.stringify()在对象中遇到undefined、function、symbol都会自动忽略掉,而在数组中就会返回null

    <script>
      var a = null;
      var b = undefined;
      var d = function foo() {};
      var c = [1, undefined, d, null];
      console.log("c: ", JSON.stringify(c));
      console.log("a: ", JSON.stringify(a));
      console.log("b: ", JSON.stringify(b));
    </script>

image-20211210170120749

2、JSON.stringify()对数组的返回与toString()返回的结果不一样,如下

    <script>
      var a = [1, 2, 3];
      console.log("toString()", a.toString(a)); // '1','2','3'
      console.log("JSON.stringify()", JSON.stringify(a)); // '[1,2,3]'
    </script>

image-20211210170622921

JSON.stringify()中还可以接一个参数,这里不做过多扩展,只是简单展示与其他方法的区别,注意,JSON.stringify()不是强制类型转换

额外扩展:在JSON.stringify()中还会存在toJSON()方法,JSON字符串首先会调用该方法,然后用其返回值去进行序列化

toJSON()返回的是一个能够被字符串化的安全的JSON值,而不是一个JSON字符串

日期显示转数字

这部分知识在工作中比较重要,我们很多时候需要获得当前时间的时间戳,或者v-for、map中都需要key值,偶尔我们会没有key值,我们就可以用写一个js文件,封装获得时间戳+随机字符数字的集合来作为Key值,或者利用第三方库也行。这里做相关介绍

日期函数:是js中的全局函数

Date()

    <script>
      var a = new Date();
      var b = new Date().getTime();
      var c = Date.now();
      
      console.log("先强制类型转换", +a);
      console.log("Date中的内置函数getTime()", b);
      console.log("ES5的now()", c);
    </script>

image-20211211110047069

数字

非数字转换为数字类型

首先举出一些列子,也可能是常见的面试资源

true 转换为 1

false 转换为 0

null 转换为 0

undefined转换为 NAN

1、Number()

这是js中的全局函数

<script>
      var a = "22";
      var b = null;
      var c = undefined;
      var d = true;
      var e = false;
      var f = {};
      var g = [];
      var h = function foo() {};
      console.log(Number(a));
      console.log(Number(b));
      console.log(Number(c));
      console.log(Number(d));
      console.log(Number(e));
      console.log(Number(f));
      console.log(Number(g));
      console.log(Number(h));
    </script>

image-20211210225350698

可以看到 函数与对象转换为了NAN

2、parseInt()

字符串转数字取整形,还可以接一个参数,确定返回数为几进制,这里不展开

parseInt()与Number()的区别:

1、前者在转换字符串的过程中若是遇到非字符数字的会终止,但是转换的数会被输出,后者就会转换失败,报出NAN

2、前者转换中会先进行一次强制类型转换,转换为字符串类型,再去把字符串转换为数字,所以使用parseInt()前的数值最好是字符串型的

具体的如下列:

    <script>
      var a = "33";
      var b = [1, 2, 3];
      var c = {};
      var d = function () {};
      console.log(parseInt(a));
      console.log(parseInt(b));
      console.log(parseInt(c));
      console.log(parseInt(d));
      console.log('');
      console.log(Number(a));
      console.log(Number(b));
      console.log(Number(c));
      console.log(Number(d));
    </script>

image-20211211110901550

3、parseFloat()

字符串类型的转换为数字型的浮点数,具体用法和parseInt()类似,详细的区别不过多介绍

4、隐式转换

隐式转换有两种方式

方式一

这是显示强制类型转换

使用一元运算符+,上面只是有简单提起,注意的是若+左右侧任意一方是字符串类型,则为字符串拼接

 <script>
      var a = "1";
      var b = null;
      var c = undefined;
      var e = {};
      var f = function () {};
      console.log("隐式转换方式一", +a, typeof +a);
      console.log("隐式转换方式一", +b, typeof +b);
      console.log("隐式转换方式一", +c, typeof +c);
      console.log("隐式转换方式一", +e, typeof +e);
      console.log("隐式转换方式一", +f, typeof +f);
    </script>

image-20211210230142553

方式二

在不改变原来的值情况下,使用一元运算符-,*,%,如下列:

    <script>
      var a = "1";
      var b = null;
      var c = undefined;
      var e = {};
      var f = function () {};
      console.log("隐式转换方式二", a - 0, typeof +a);
      console.log("隐式转换方式二", b - 0, typeof +b);
      console.log("隐式转换方式二", c % 1, typeof +c);
      console.log("隐式转换方式二", e * 1, typeof +e);
      console.log("隐式转换方式二", f - 0, typeof +f);
    </script>

image-20211210230431252

布尔

非布尔类型转换为布尔类型

1、假值

我们先来认识js中的假值

undefined、null、false、+0、-0、NAN、""

这七个值被称为js中的假值,除了假值外其他的都是真值

2、假值对象

假值对象并不是假值,只是封装了价值的对象,如下:

    <script>
      var a = new Boolean(false);
      var b = new Number(0);
      var c = new String("");
      console.log(Boolean(a));
      console.log(Boolean(b));
      console.log(Boolean(c));
    </script>

image-20211211103224382

这里的价值对象需要和假值做出区分,一个是对象,一个是js中的基本类型

3、真值

介绍假值得时候说到,真值就是除假值外的值,如下列:

    <script>
      var a = "false";
      var b = '"';
      var c = "0";
      var d = [];
      var e = {};
      var f = function () {};
      console.log(Boolean(a));
      console.log(Boolean(b));
      console.log(Boolean(c));
      console.log(Boolean(d));
      console.log(Boolean(e));
      console.log(Boolean(f));
    </script>

image-20211211103627171

真值有无限多,所有我们只要记住有几种假值就好了

Boolean()是js中的全局函数,和!!操作符一样都是显示强制类型转换,下面介绍下

!!

搜先说下!,一元运算符!显示的将值强制类型转换为布尔型,但是它同时还会将真值转换为假值,假值转化为值。所以想要原来值不变,类型转换为布尔型还需要再使用一次!,这样就取反了。

上面说这么多是想表达!!不是简单的取反再取反,是进行了显示的强制类型转换。

隐式强制类型转换:数字、字符串、布尔之间的类型转换
字符串和数字之间的隐式转换

前面简单的介绍了一元操作符+的作用,这里做点补充

通过重载,js中的+运算符既能用于数字加法,又能用于字符串拼接,在js中是怎么判断的呢?

1、+会去判断左右两侧的操作数,如果某个操作数是字符串型或者能够转换为字符串型,+就会对左右两侧进行拼接

2、若是没有字符串型的,就执行加法操作

    <script>
      var a = 33;
      var b = 1;
      var c = "";
      console.log(a + b);
      console.log(a + c);
      console.log("//");

      var d = [1, 2];
      var e = [3, 4];
      console.log(d + e);
    </script>

image-20211211130244194

上面是数字到 字符串的转换,同样的若是需要字符串到数字的隐式转换可以用一元操作符-、%、*,但是是在不改变原有的值的情况下,如下:

    <script>
      var a = "3.14";
      var b = a - 0;
      console.log("b: ", b);  // '3.14'
    </script>

通过+ 和其他的一元运算符就可以进行字符串与数字之间的隐式强制类型转换

隐式强制类型转换为布尔值

在写代码的过程中我们经常会用到下面的场景,其实这里已经做了值类型的强制转换,如下 所示:

1、if()中的条件表达式

2、for() 语句中的条件判断表达式(第二个)

3、while() 和 do…while()循环中的条件判断表达式

4、? : 中的判断表达式

5、 && 和 || 左边的操作数会作为条件判断的表达式

上面列举出的这些情况,都会隐式强制类型转换把非布尔型转换为布尔型,我们重点理解下第五条

|| 和 &&

a||b a&&b

逻辑或和逻辑与,在工作中非常实用的知识点!在JS中这里其实应该叫做”选择器运算符“ ,和其他语言不同, 他们返回的并不是一个布尔值,而是两个操作数中的一个(仅且一个)

选择器运算符会先去判断左边的值不是不一个布尔值,若非布尔值的话,就会先进行值强制类转换转换为布尔值

    <script>
      var a = 42;
      var b = null;
      var c = "abc";
      console.log(a && c);
      console.log(a && b);
      console.log("/");
      console.log(a || c);
      console.log(a || b);
      console.log(b || a);
    </script>

image-20211211132020353

如上所示,这里打印出的并不是true和false,而是选择器运算符左侧或者右侧的一个操作数,他们遵循下面的这些规则:

a||b、a&&b

1、当为||选择器运算符的时候,如果a为true,则选择操作数a,否则选则b

2、当为&&选择器运算符的时候,如果a为true,则选择操作数b,否则选择a

这里的第一个操作数的真假值判断可以参考上面的假值得内容

这里是不是很好奇,既然||与&&返回的不是true和false,为什么if()判断条件中可以使用&&和||,如下列:

    <script>
      var a = 42;
      var b = null;
      var c = "foo";
      if (a && (b || c)) {
        console.log("yep");  // 输出的是yep
        
      }
    </script>

我们在这一小节的开始就说到,在举列子中得条件判断中,会自动将非布尔型得数值转换为布尔值的类型,所意这个列子如下解析:

1、b||c,b是null为假值,||第一个操作数为假的情况下,取第二个操作数,就是c

2、a&&c,a是42,为真值,&&第一个操作数为真的情况下,取第二个操作数,就是’foo‘

3、就得到 if(“foo”),前面说过,if()中会进行值的类型转换,”foo“的值为真,所以if()条件判断为真,打印log

上面都是进行了隐式的强制类型转换,如果需要避免进行隐式强制类型转换,可以这样写:

    <script>
      var a = 42;
      var b = null;
      var c = "foo";
      if (!!a && (!!b || !!c)) {
        console.log("yep");
      }
    </script>
符号的强制类型转换

符号 Symbol是ES6新增的一个常用基本类型,这里简单的介绍下关于Symbol的强制类型转换。

关于他的值类型转换有一个坑:ES6允许从符号到字符串的显示强制类型转换,而隐式的强制类型转换就会报错,原因可自行百度,列子如下:

    <script>
      var a = Symbol("cool");
      console.log(String(a));
      console.log(a + "");
    </script>

image-20211211135821900

对于符号的值强制类型转换,我们可记住下面这几点:

1、符号转字符串形式,只能显示强制类型转换,隐式强制类型转换会报错

2、符号不能被强值转换为数字,不管是显示还是隐式都会报错

3、符号转布尔型,隐式和显示的结果都是true

这里简单的记一下就好,具体的知识点需要单独的看看

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐