为了将值转换为基本类型值(string,number,boolean,null,undefined),抽象操作ToPrimitive会首先检查该值有没有valueOf()方法,如果有并且返回基本类型值,那么使用该值进行强制类型转换,如果没有就使用toString()的返回值进行强制类型转换。如果valueOf()和toString()均不返回基本类型值,那么会产生TypeError错误。

一、其他类型的值转换成字符串的规则 ToString

1)null转换为"null"

2)_undefined转换为"undefined"

3)数字转换为对应的数字字符串

4)普通对象,除非自行定义,否则会调用默认的toString()方法(Object.prototype.toString()),返回内部属性[[class]]的值。

5)数组的toString()方法经过了重新定义,会将所有单元字符串化之后用,连接起来。如[1,2]转换为1,2;[]转换为'';(数组的valueof会返回数组本身)

二、其他类型的值转换为数字的规则 ToNumber

1)true转换为1,false转换为0

2)undefined转换为NaN

3)null转换为0

4)数字字符串转换为对应数字,如果字符串不是数字形式,转换失败返回NaN。'',\n,'  ' 的toNumber返回0.

5)对象,包括数组会首先被转换为基本类型值(方法见本篇开头),如果返回的是非数字的基本类型值,则再遵循上述规则将其强制转换为数字。

三、数字字符串和数字之间的显式强制转换

(凡是需要调用函数的开销一般较大,不推荐)

数字转换为字符串:

var a=23;
var b=String(a);//能转换,不推荐
var b=a.toString();//能转换,不推荐
var b=a+'';//推荐

字符串转换为数字:

var a=‘23’;
var b=Number(a);//能转换,但不推荐
var b=+a;//推荐

注意,转换数字字符串与解析数字字符串是不同的概念。

parseInt与parseFloat可以解析数字字符串(注意,参数一定是字符串)。解析允许字符串中含有非数字字符,解析按照从左向右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否则会失败并返回NaN。判断字符串是否为数字字符串可以使用isFinite,如isFinite('123abc'),返回false。

三、将其他类型的值转换为布尔值的规则 ToBoolean

javascript的值可以分为两类:

1)可以强制转换为false的值(false or false-like):包括null,undefined,'',+0,-0,NaN

2)其他。如"0",[],{}强制转换为布尔值的话,都为true

将其他类型的值显示转换为布尔值可以使用Boolean(a)(不建议)和!!a(建议)这两种方式。

与上述显式强制类型转换对应的还有一类隐式强制类型转换(多指在运算中,或者条件判断中静默发生的类型转换)。

四、宽松相等(==)与严格相等(===)

二者的区别在于,==允许在相等比较中进行强制类型转换,而===则不允许。

有几个非常规的情况值得注意:

NaN不等于NaN,这是一个唯一不具有自反性的值。

+0等于-0.

1.字符串和数字之间的相等(==)比较

1)如果Type(x)是数字,Type(y)是字符串,则返回x==ToNumber(y)的结果。

2)如果Type(y)是数字,Type(x)是字符串,则返回ToNumber(x)==y的结果。

总之,就是想办法让等号两边都成为数字之后,再比较。

2.其他类型的值与布尔值相等比较

1)如果Type(x)是布尔值,Type(y)是字符串,则返回ToNumber(x)==y的结果。

2)如果Type(y)是布尔值,Type(x)是字符串,则返回x==ToNumber(y)的结果。

总之,就是让布尔值先转换为数字。

3.null与undefined之间的比较。

null==undefined与undefined==null,这两者是成立的。也就是说,==中null与undefined是等价的。除此之外的任何值都!=null或者undefined.

4.对象和非对象之间的相等比较

1)如果Type(x)是字符串或者数字,Type(y)是对象,则返回x==ToPrimitive(y)的结果。

2)如果Type(x)是对象,Type(y)是字符串或者数字,则返回ToPrimitive(x)==y的结果。

这里没有提到布尔值,是因为之前说过,布尔值会被首先转换为数字。

总之,就是先调用对象的toPrimitive再比较

上面这些规则有时候会出现一些乍一看很晕的结果,如:

false==[].//true

false=={}//false

[]==![]//true

有两个原则可以让我们尽量避免出错:

1)如果两边的值中有true或者false,千万不要使用==。

如:可以直接用if(a),if(!!a),if(a===true).不要使用if(a==true)

2)如果两边的值中有'',0或者[],尽量不要用==。

这时尽量用===来避免不经意的类型转换。

上述两个规则可以让我们避开几乎所有强制类型转换的坑。

javascript中的类型转换,宽松相等于严格相等的更多相关文章

  1. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

  2. JavaScript中的类型转换(二)

    说明: 本篇主要讨论JavaScript中各运算符对运算数进行的类型转换的影响,本文中所提到的对象类型仅指JavaScript预定义的类型和程序员自己实现的对象,不包括宿主环境定义的特殊对象(比如浏览 ...

  3. JavaScript中的类型转换(一)

    前言 JavaScript是一种非常灵活的弱类型的语言,它的灵活性的一方面体现在其繁杂多样的类型转换.比如当JavaScript期望使用一个布尔值的时候(比如if语句中)你可以提供任一类型的值,Jav ...

  4. [翻译]解释JavaScript中的类型转换

    原文地址:JavaScript type coercion explained 类型转换是将值从一种类型转换为另一种类型的过程(比如字符串转换为数值,对象转换为布尔值,等等).任何类型,无论是原始类型 ...

  5. 【你不知道的javaScript 中卷 笔记2】javaScript中的类型转换

    1.1 对象内部属性 [[Class]] 常见的原生函数: String() Number() Boolean() Array() Object() Function() RegExp() Date( ...

  6. javascript中强制类型转换

    javascript开发过程中,强制类型转换一般发生在条件判断和==运算符.其他情况,发生的类型转换(与这两种情况也是基本类似,属于万变不离其宗的范畴),暂不讨论. == 双等运算符 考虑代码: a ...

  7. javascript中数据类型转换

    转换为数字: parseInt():转换为整数型数值:从下标0开始判断,若为数值型则继续直到遇到非数值,返回前面的整数值: 小数点无效,若0开始为非数值则返回NaN: 转换空字符串会返回NaN: 能转 ...

  8. javascript中的类型转换(进制转换|位运算)

    1:parseInt(string) : 这个函数的功能是从string的开头开始解析,返回一个整数 parseInt("123hua"); //输出 123 parseInt(& ...

  9. js | JavaScript中数据类型转换总结

    转载 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = “123”; a = Number(a); ...

随机推荐

  1. Lambda表达式使用方法整理

    匿名内部类                                                                               Lambda表达式 匿名内部类  ...

  2. WebStorm 2017 最新激活方式

    刚开始使用WebStorm注册时,在打开的License Activation窗口中选择“activation code”,在输入框输入下面的注册码 43B4A73YYJ-eyJsaWNlbnNlSW ...

  3. DDD 理解

    DDD提倡充血模型,业务放在类中,而不是服务中,刚开始是比较不清楚的.突然明白,以前开发桌面程序的时候,不就是这样处理了吗?业务分析和代码实现一一对应.因为桌面程序没有数据库,他就是纯粹的面向对象的实 ...

  4. H5的本地存储(localStorage)和cookie比较

    HTML5 的 web Storage 存储方式有两种:localStorage 和 sessionStorage. sessionStorage就像是会话级别的cookie,数据会随着浏览器关闭而清 ...

  5. ES6复制数组

    ES6复制数组和合并数组 一.复制数组与合并数组 复制数组:它是复合数据类型,直接复制只是复制了指向底层数据结构的指针,而不是复制一个全新的数组 <!DOCTYPE html> <h ...

  6. 解决微信小程序Date.parse()获取时间戳IOS显示为NaN

    ios系统不支持2018-03-29这样格式的时间导致出现的这个问题, IOS只识别2018/03/09这样的格式. 上正则 //之前的var data = '2018-03-09 12:00:00' ...

  7. Python与C/C++相互调用(转)

    原文链接 作者 一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库 ...

  8. 使用LaTeX和KnitR自动生成报告

    扩展名为.Rnw(Rtex)的文件就是包含了R代码的LaTeX文档.编译的时候,先用Rscript调用Knitr处理,生成.TeX文档,然后用pdfLaTeX/XeLaTeX编译成PDF. 最方便的编 ...

  9. Django 开发相关知识 整理

    前言 前端ajax HTTP请求头 ajax上传文件 jsonp跨域 URL 设计 分发 url参数编码 反向生成url 视图 request对象 POST url信息 视图返回值 HttpRespo ...

  10. Junit5常用注解

    0. IDEA中Maven项目测试类的新建方法 a. 如图在src目录下新建文件夹test b. 鼠标右键test,将该文件设置成test source c. 右键需要新建的测试类,如下图操作,选中T ...