JavaScript核心概念(1):类型转换

看到这个是不是有一种想打人的感觉,垃圾 JavaScript,这特么都什么鬼,相信很多人不管是笔试还是面试,都被 JS 的类型转换难道过,相信认真看完我这篇文章,妈妈再也不用担心类型转换的问题了。

原始值到原始值的转换

  1. 原始值转化为布尔值 所有的假值(undefined、null、0、-0、NaN、””)会被转化为 false,其他都会被转为 true
  2. 原始值转化为字符串 都相当于 原始值 + ""
  3. 原始值转为数字 +" 66" // 66 +" 6 7 " // NaN
    • 布尔转数字:true -> 1, false -> 0
    • 字符串转数字:以数字表示的字符串可以直接会转为字符串,如果字符串头尾有空格会忽略,但是空格在中间,转换结果就是 NaN。

原始值到对象的转换

  • null 和 undefined 转对象直接抛异常
  • 原始值通过调用 String()、Number()、Boolean()构造函数,转换为他们各自的包装对象

对象到原始值的转换

  1. 对象转为布尔都为 true
  2. 对象到字符串
    • 如果对象有 toString() 方法,就调用 toString() 方法。如果该方法返回原始值,就讲这个值转化为字符串。
    • 如果对象没有 toString() 方法或者 该方法返回的不是原始值,就会调用该对象的 valueOf() 方法。如果存在就调用这个方法,如果返回值是原始值,就转化为字符串。
    • 否则就报错
  3. 对象到数字
    • 对象转化为数字做了跟对象转化为字符串做了想同的事儿,不同的是后者是先调用 valueOf 方法,如果调用失败或者返回不是原始值,就调用 toString 方法。
  4. 补充。一些常用内置对象 toString 方法和 valueOf 的转换规则
    • toString 相关
    • valueOf 相关

== 运算符如何进行类型转换

  1. 如果一个值是null,另一个值是undefined,则相等
  2. 如果一个是字符串,另一个值是数字,则把字符串转换成数字,进行比较
  3. 如果任意值是true,则把true转换成1再进行比较;如果任意值是false,则把false转换成0再进行比较
  4. 如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的 toString 或者 valueOf 方法。 js 核心内置类,会尝试 valueOf 先于 toString(可以理解为对象优先转换成数字);例外的是 Date,Date 利用的是 toString 转换。非 js 核心的对象,通过自己的实现中定义的方法转换成原始值。

+ 运算符如何进行类型转化

  1. 如果作为一元运算符就是转化为数字,常常用来将字符串转化为数字 +"2" // 2 2+false // 0
  2. 如果作为二元运算符就有两种转换方式
    • 两边如果有字符串,另一边一会转化为字符串进行相加
    • 如果没有字符串,两边都会转化为数字进行相加,对象也根据前面的方法转化为原始值数字。
    • 如果其中的一个操作数是对象,则将对象转换成原始值,日期对象会通过 toString() 方法进行转换,其他对象通过 valueOf()方法进行转换,但是大多数方法都是不具备可用的 valueOf() 方法,所以还是会通过 toString() 方法执行转换。

流程图如下:

实战分析

1. []+[] // ""

_1. 首先运算符是 + 运算符而且很明显是二元运算符,并且有对象,所以选择最后一点,操作数是对象,将对象转换为原始值。

_2. 两边对象都是数组,左边的数组先调用 valueOf() 方法无果,然后去调用 toString(), 方法,在 toString() 的转化规则里面有『将数组转化为字符串,用逗号分隔』,由于没有其他元素,所以直接是空字符串 “”。

_3. 因为加号有一边是字符串了,所以另外一边也转为 字符串,所以两边都是空字符串 “”。

_4. 所以加起来也是空字符串 “”。

2. (! + [] + [] + ![]).length // 9

_1. 首先我们会看到挺多一元运算符,「+」、「!」,对于一元运算符是右结合性,所以可以画出以下运算顺序。

_2. 对于+[],数组是会被转化为数字的而不是字符串,可见「+ 运算符如何进行类型转化」的第一条,所以经过第一步就会转化为

(!0 + [] + "false").length

_3. 第二步比较简单,0 转化为布尔值就是 false,所以经过第二步就转化为

(true + [] + "false").length

_4. 第三步中间的 []会转为空字符串,在「+ 运算符如何进行类型转化」第二条的第三点,对象会被转转化为原始值,就是空字符,所以经过第三步之后就会变成

("true" + "false").length

_5. 第五步就比较简单啦,最终就是

"truefalse".length // 9

附录:

《JavaScript权威指南》中类型转换表格

原文发布于微信公众号 - 前端桃园(betaoyuan)

原文发表时间:2018-08-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黑泽君的专栏

java基础学习_面向对象(上)02_day07总结

============================================================================= ==...

751
来自专栏http://www.cnblogs.com

python3 re模块

一.常用正则表达式符号和语法: '.' 匹配所有字符串,除\n以外 ‘-’ 表示范围[0-9] '*' 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 ...

46112
来自专栏PPV课数据科学社区

Python 正则表达式

? 简介 正则表达式(regular expression)是可以匹配文本片段的模式。最简单的正则表达式就是普通字符串,可以匹配其自身。比如,正则表达式 ‘h...

4026
来自专栏柠檬先生

Java 基础标识符

标识符: 程序员为自己定义的类,方法或者变量等起的名称。     标识符由大写字母,数字,下划线(_)和美元符号组成,但不能以数字开头。 Java 语言中严格区...

2125
来自专栏水击三千

JavaScript函数(二)

在前面我们已经对函数作了简单的介绍,比如函数的定义、函数的声明、函数的调用和函数的传参等。本节将进一步介绍函数的应用,深度理解函数的各种使用。 函数是一个对象,...

2857
来自专栏开发与安全

从零开始学C++之构造函数与析构函数(一):构造函数、析构函数、赋值与初始化、explicit关键字

一、构造函数、默认构造函数 (1)、构造函数 构造函数是特殊的成员函数 创建类类型的新对象,系统自动会调用构造函数 构造函数是为了保证对象的每个数据成员都...

2590
来自专栏和蔼的张星的图像处理专栏

64. 合并排序数组 II 三指针+从后向前

合并两个排序的整数数组A和B变成一个新的数组。 注意事项 你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素。 样例 给出A =...

1151
来自专栏python学习指南

Scala学习笔记之二--基本数据类型

前言 本篇主要讲Scala的基本数据类型,更多教程请参考:Scala教程 基本数据类型 Scala一共提供了9中数据类型,Scala的基本数据类型与j...

2235
来自专栏机器学习从入门到成神

关于Java中==与equals的解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

720
来自专栏欧阳大哥的轮子

C++运算符重载详解

C++语言的一个很有意思的特性就是除了支持函数重载外还支持运算符重载,原因就是在C++看来运算符也算是一种函数。比如一个 a + b 的加法表达式也可以用函数的...

2053

扫码关注云+社区

领取腾讯云代金券