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

敏捷开发
• 阅读 1524
本文首发于个人博客

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

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

原始值到原始值的转换

  1. 原始值转化为布尔值

    所有的假值(undefined、null、0、-0、NaN、””)会被转化为 false,其他都会被转为 true

  2. 原始值转化为字符串
    都相当于 原始值 + ""
  3. 原始值转为数字

    • 布尔转数字:true -> 1, false -> 0
    • 字符串转数字:以数字表示的字符串可以直接会转为字符串,如果字符串头尾有空格会忽略,但是空格在中间,转换结果就是 NaN。

        +" 66" // 66
        +" 6 7 " // NaN

原始值到对象的转换

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

对象到原始值的转换

  1. 对象转为布尔都为 true
  2. 对象到字符串

    • 如果对象有 toString() 方法,就调用 toString() 方法。如果该方法返回原始值,就讲这个值转化为字符串。
    • 如果对象没有 toString() 方法或者 该方法返回的不是原始值,就会调用该对象的 valueOf() 方法。如果存在就调用这个方法,如果返回值是原始值,就转化为字符串。
    • 否则就报错
  3. 对象到数字

    • 对象转化为数字做了跟对象转化为字符串做了想同的事儿,不同的是后者是先调用 valueOf 方法,如果调用失败或者返回不是原始值,就调用 toString 方法。
  4. 补充。一些常用内置对象 toString 方法和 valueOf 的转换规则

    • toString 相关

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

- valueOf 相关

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

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

  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() 方法执行转换。

流程图如下:
JavaScript核心概念(1):类型转换

实战分析

1. []+[] // ""

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

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

![](https://user-gold-cdn.xitu.io/2018/8/7/165124228cd61ccc?w=236&h=64&f=png&s=2453)

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

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

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

_1. 首先我们会看到挺多一元运算符,「+」、「!」,对于一元运算符是右结合性,所以可以画出以下运算顺序。
JavaScript核心概念(1):类型转换

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

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

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

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

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

("true" + "false").length

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

"truefalse".length // 9

附录:

JavaScript核心概念(1):类型转换
《JavaScript权威指南》中类型转换表格

JavaScript核心概念(1):类型转换
个人公众号,欢迎继续交流

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Easter79 Easter79
4年前
typeScript数据类型
//布尔类型letisDone:booleanfalse;//数字类型所有数字都是浮点数numberletdecLiteral:number6;lethexLiteral:number0xf00d;letbinaryLiteral:number0b101
Stella981 Stella981
4年前
List的Select 和Select().tolist()
List<PersondelpnewList<Person{newPerson{Id1,Name"小明1",Age11,Sign0},newPerson{Id2,Name"小明2",Age12,
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这