本文中提到的“原始值”指的是undefined,null,Boolean,string和number。

本文中的对象是native对象,宿主对象(浏览器定义的对象)按照各自的算法转换。

JavaScript中共有六种数据类型,Undefined、Null、Boolean、Number、String和Object。

关于类型转换,JavaScript很有趣的一点是,它会根据他期待的数据类型自动进行类型转换。也就是说,即便你不给他他想要的,他也会自己动手把你给的变成他想要的。

那么这里就有两个问题,他期待什么和他怎么变
 
我们先来看,他怎么变?
 
我们知道,JavaScript中有用于类型转换的函数,比如String( ),Number( ),Boolean( ),Object( )。通过这些方法,我们可以显式的将数据转换为想要的类型。
下图是《JavaScript权威指南》中给各种数据类型相互转换的结果:

原始值的转换都很简单,和我们想象的几乎一致,其中复杂的是对象到原始值的转换,所以要单独进行讨论。

3.8.3中介绍了对象转换为不同类型的过程,不管要转换成什么类型,都是通过调用JavaScript会使用对象的两个转换方法——valueOf( )和toString( )来获得原始值,获取结果如下表:

只不过转换为不同类型获取原始值规则不同。

  • 将对象转换为字符串的规则:
  1. 如果他有toString( ),调用,如果他返回一个原始值,将其转换为为字符串(如果不是字符串)并返回。
  2. 如果他返回的不是原始值,或他没有toString( ), 调用valueOf( ),如果返回一个原始值,将其转换为字符串(如果不是字符串)并返回 。
  3. 否则,抛出一个类型错误异常。
  • 将对象转换为数字的规则:
  1. 先尝试用valueOf( ),如果返回一个原始值,再将其转换为数值并返回。
  2. 如果返回的不是原始值或他没有valueOf( ),再尝试toString( ),如果返回一个原始值,将其转换为数值并返回。
  3. 否则,抛出一个类型错误异常。
以上是对数据类型进行显性转换的规则。
 
之前我们说了,JavaScript会根据自身需要对数据进行隐式转换
 
这就需要知道,他期待什么?也就是说,什么时候他会做出隐式转换这个行为。
 
  • 当它执行"!"操作符和if语句时,它会期待一个布尔值,如果你给他的不是一个布尔值,他会后台调用Boolean( )将其操作数转换为布尔值。
                   所以 !!x 就相当于Boolean(x)
  • 当它执行"-"或一元"+"操作符时,它会期待一或两个数值,如果你给他的不是数值,他会后台调用Number( )将其操作数转换为数值。
                   所以 x-0 就相当于Number(x)
                         +x  就相当于Number(x)
  • 当它执行 二元"+","=="("!="),和关系操作符时,会根据自身的期待进行类型转换。
            而不管它们期待什么,有一点是相同的,就是当他们遇到一个对象的时候,它们会将对象转换为原始值直接做为结果返回,然后再根据各自的期待进行类型转换。
            它们返回原始值的规则都是:非日期对象先尝试调用valueOf(),不行再调用toString();日期对象调用toString( )。
           
         然后我们可以看看它们各自的期待:
                 二元“+”,期待数字或字符串,最期待字符串,其他类型都将进行类型转换。
                       也就是说,只要有一个是字符串,他就会期待字符串,然后调用String( )将非字符串转换为字符串。
                       如果两个都不是字符串,他才会调用Number( )将两个操作数都转换为数值。
                       如果其中一个是对象,将其转换为原始值,再和另一个操作数比较,决定如何行动。
                               所以x+""就相当于String(x)
 
                 关系操作符("<",">","<=",">=" ),期待数字和字符串,最期待数值,其他类型的操作数将进行类型转换:
                        如果操作数是对象,转换为原始值。(先调用valueOf(除了日期对象),直接返回结果,不强制转换为数字或字符串。)
                        转换之后,如果都是字符串,那么依照字母表顺序比较,如果至少有一个不是字符串,那么两个操作数都将转换为数值进行比较。
 
                 "=="("!=")的规则:
                         1.相同类型的按照===的规则比较。
                         2.不同类型的:
                              ①undefined==null
                              ②字符串和数字,将字符串转换为数字。
                              ③布尔值和数字,将布尔值转换为数字。
                              ④如果一个值是对象,另一个是数字或字符串。将对象转换为原始值。非JavaScript核心中的对象则通过各自的实现中定义的方法转换为原始值。
                              ⑤其他不同类型的比较均不相等。
 
 
利用以上知识,我们就可以理解一些简洁的代码是如何达到目的的了:
  • +date 返回表示日期的毫秒数(date是日期对象。 )
           因为+会将操作数转换为数字,而date是一个对象,所以会先调用对象的valueOf()方法,日期对象的这个方法会返回表示这个日期的毫秒数。
  • if(-[1,]) 在非IE6/7/8中的值为true,在IE6/7/8中为false。
           第一步,执行"-"。因为"-"操作符会将操作数转换为数值,数组是一个对象,会调用其valueOf方法,返回一个对象,所以继续调用其toString( )方法,非IE6/7/8的JS引擎会自动去除数组最后的逗号,所以结果为[1],[1]被转换为数值,即1;而IE6/7/8的JS引擎不会自动剔除数组中的最后的逗号,所以其valueOf的返回值为“1,”,转换为数字得到NaN;
           第二步,执行if语句。if语句期待一个布尔值,将-1转换为布尔值为true。将(-NaN)转换为布尔值得到false。
 
 
JavaScript的这个特点非常灵活,可以利用它减少很多代码。不过有利就有弊,如果我们没有理解它的运作机理,很可能一不小心就被它坑了。所以我们平时写代码的时候一定要注意它的隐式转换行为。
 
 

JavaScript中的数据类型转换的更多相关文章

  1. 第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据

    第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据 学习要点: 1.JSON语法 2.解析和序列化 前两章我们探讨了XML的结构化数据,但开发人员还是觉得这 ...

  2. 谈 JavaScript 中的强制类型转换 (2. 应用篇)

    这一部分内容是承接上一篇的, 建议先阅读谈 JavaScript 中的强制类型转换 (1. 基础篇) 前两章讨论了基本数据类型和基本包装类型的关系, 以及两个在类型转换中十分重要的方法: valueO ...

  3. 详细理解javascript中的强制类型转换

    将值从一种类型转换为另一种类型通常称为类型转换,这是显式的情况:隐式的情况称为强制类型转换,JavaScript 中的强制类型转换总是返回标量基本类型值,如字符串.数字和布尔值. 如何理解: 类型转换 ...

  4. 浅谈 JavaScript 中常用数据及其类型转换

    在 JavaScript 中有一些 value 会经常碰到: [] (空数组).{} (空对象).'' (空字符串).undefined.null.0.NaN.Infinite 也会经常碰到数据类型转 ...

  5. 谈 JavaScript 中的强制类型转换 (1. 基础篇)

    1. 从基本包装类型讲起 讨论基本包装类型的前提是了解基本数据类型(也可以称为原始类型, 简单数据类型等).然后通过基本数据类型调用方法的行为, 引出基本包装类型的概念和作用. 1.1 基本数据类型 ...

  6. C语言中强制数据类型转换(转)

    原文地址不详 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255(有些 ...

  7. javascript中 json数据的解析与序列化

    首先明确一下概念: json格式数据本质上就是字符串: js对象:JavaScript 中的几乎所有事务都是对象:字符串.数字.数组.日期.函数,等等. json数据的解析: 就是把后端传来的json ...

  8. Java中的数据类型转换

    先来看一个题: Java类Demo中存在方法func0.func1.func2.func3和func4,请问该方法中,哪些是不合法的定义?( ) public class Demo{ float fu ...

  9. matlab中图片数据类型转换uint8与double

    matlab中处理图像像素点数据: img1=double(imread('lenna.bmp')); matlab中imshow图片,要先转换成uint8: subplot(1,2,1),imsho ...

随机推荐

  1. 如何设置mysql远程访问及防火墙设置

    笔者在一个实际的项目中需要MYSQL远程访问. 情景: 安装好Mysql, 本地访问正常,很奇怪局域的机器都无法访问该服务器上的MYSQL数据库. 经过资料查找 原来Mysql默认是不可以通过远程机器 ...

  2. 【一】Ubuntu14.04+Jekyll+Github Pages搭建静态博客

    本系列有五篇:分别是 [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面 [二]jekyll 的使用 :主要是jekyll的配置 [三]Markdown+ ...

  3. 系统吞吐量(TPS)、用户并发量、性能测试概念和公式

    分享一个概念: http://www.ha97.com/5095.html

  4. 玩转JavaScript OOP[2]——类的实现

    概述 当我们在谈论面向对象编程时,我们在谈论什么?我们首先谈论的是一些概念:对象.类.封装.继承.多态.对象和类是面向对象的基础,封装.继承和多态是面向对象编程的三大特性. JavaScript提供了 ...

  5. [Linux] linux下安装配置 zookeeper/redis/solr/tomcat/IK分词器 详细实例.

    今天 不知自己装的centos 出现了什么问题, 一直卡在 启动界面, 找了半天没找见原因(最后时刻还是发现原因, 只因自己手欠一怒之下将centos删除了, 而且选择的是在本地磁盘也删除. ..让我 ...

  6. JMeter--二、在Windows环境上搭建wordpress

    为了学习使用JMeter,在Windows环境上搭建了wordpress. 使用JMeter录制或是编写登录worepress.编辑文章.删除文章的脚本. 首先了解一下wordpress是什么? Wo ...

  7. Android笔记——permission权限大全

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...

  8. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...

  9. webpack的安装和使用

    Webpack是什么 首先可以看下 官方文档 ,文档是最好的老师. Webpack是由Tobias Koppers开发的一个开源前端模块构建工具.它的基本功能是将以模块格式书写的多个JavaScrip ...

  10. 解密jQuery内核 DOM操作的核心buildFragment

    文档碎片是什么 http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-B63ED1A3 DocumentFragment is a & ...