JavaScript中通常分为两种类型转换,“隐式强制类型转换”(implicit coercion)和“显式强制类型转换”(explicit coercion)。

下面所有代码的源码可以在此处查看

一、强制转换为字符串(ToString)

1)ToString

基本类型值的字符串化规则为:null转换为"null",undefined转换为"undefined",true转换为"true"。数字的字符串化则遵循通用规则,不过那些极小和极大的数字使用指数形式:

// 1.07 连续乘以七个 1000
var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
// 七个1000一共21位数字
console.log(a.toString()); // "1.07e21"

对普通对象来说,除非自行定义,否则toString()(Object.prototype.toString())返回内部属性[[Class]]的值

2)JSON

JSON.stringify(..)在对象中遇到undefined、function和symbol时会自动将其忽略,在数组中则会返回null(以保证单元位置不变)。

如果对象中定义了toJSON()方法,JSON字符串化时会首先调用该方法,然后用它的返回值来进行序列化。

JSON.stringify(undefined); // undefined
JSON.stringify(function() {}); // undefined JSON.stringify(
[1, undefined, function() {}, 4]
); // "[1,null,null,4]"
JSON.stringify({
a: 2,
b: function() {}
}) // "{"a":2}"

二、强制转换数字(ToNumber)

1)ToNumber

1. true转换为1false转换为0

2. undefined转换为NaNnull转换为0

3. ""[]转换为0。处理失败时返回NaN

4. ToNumber对以0开头的十六进制数并不按十六进制处理

2)对象

对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

为了将值转换为相应的基本类型值,抽象操作ToPrimitive会首先(通过内部操作DefaultValue)检查该值是否有valueOf()方法。

如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用toString()的返回值(如果存在)来进行强制类型转换。

var a = {
valueOf: function() { //先执行valueOf
return "42";
}
};
var b = {
toString: function() { //再执行toString
return "42";
}
};
var c = [4, 2];
c.toString = function() {
return this.join(""); // "42"
};
Number(a); //
Number(b); //
Number(c); //
Number(""); //
Number([]); //
Number(["abc"]); // NaN

三、强制转换布尔值(ToBoolean)

1)假值(falsy value)

可强制类型转换为false。包括undefinednullfalse+0-0NaN""

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

2)真值

[]{}function(){}都不在假值列表中。

[]、{}和function(){}

四、显式强制类型转换

1)奇特的~运算符

~x大致等同于-(x+1)

~42;    // -(42+1) ==> -43

用~~来截除数字值的小数部分~~中的第一个~执行ToInt32并反转字位,然后第二个~再进行一次字位反转,即将所有字位反转回原值,最后得到的仍然是ToInt32的结果。

//奇特的~
var a = "Hello World";
if (~a.indexOf("lo")) { //如果未找到就返回-1,(-1+1)=0就是false
// 找到匹配!
} //~~
Math.floor(-49.6); // -50
~~-49.6; // -49

2)显式解析数字字符串

解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。

转换不允许出现非数字字符,否则会失败并返回NaN。

var a = "42";
var b = "42px";
Number(a); //
parseInt(a); // Number(b); // NaN
parseInt(b); //

解析字符串中的浮点数可以使用 parseFloat(..) 函数。

非字符串参数会首先被强制类型转换为字符串(执行toString方法)。

parseInt(0.000008); // 0 ("0" 来自于 "0.000008")
parseInt(0.0000008); // 8 ("8" 来自于 "8e-7")
parseInt(false, 16); // 250 ("fa" 来自于 "false")
parseInt(parseInt, 16); // 15 ("f" 来自于 "function..") parseInt("0x10"); // 16
parseInt("103", 2); //

五、隐式强制类型

1)字符串和数字之间的隐式强制类型转换

如果+其中一个操作数是字符串则执行字符串拼接;否则执行数字加法。

如果其中一个操作数是对象(包括数组), 则对其调用 ToPrimitive 抽象操作。

var a = "42";
var b = "0";
a + b; // "420" 两个都是字符串
var c = 42;
var d = 0;
c + d; // 42 两个都是数字
var a = [1, 2];
var b = [3, 4];
a + b; // "1,23,4" 两个都是对象

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

以下情况,非布尔值会被隐式强制类型转换为布尔值,遵循ToBoolean 抽 象操作规则。

1. if (..)语句中的条件判断表达式。

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

3. while (..)do..while(..)循环中的条件判断表达式。

4. ? :中的条件判断表达式。

5.  逻辑运算符||(逻辑或)和&&(逻辑与)左边的操作数(作为条件判断表达式)。

六、宽松相等和严格相等

常见的误区是“ == 检查值是否相等, === 检查值和类型是否相等”。听起来蛮有道理,然而 还不够准确。

正确的解释是:“ == 允许在相等比较中进行强制类型转换,而 === 不允许

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

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

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

2)其他类型和布尔类型之间的相等比较

1.如果 Type(x) 是布尔类型,则返回 ToNumber(x) == y 的结果。

2.如果 Type(y) 是布尔类型,则返回 x == ToNumber(y) 的结果。

3)null 和 undefined 之间的相等比较

1.如果 x 为 null , y 为 undefined ,则结果为 true 。

2.如果 x 为 undefined , y 为 null ,则结果为 true 。

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

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

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

var a = "abc";
var b = Object(a); // 和new String( a )一样
a === b; // false
//b 通过 ToPromitive 进行强制类型转换(也称为“拆封”,unboxed或者unwrapped) ,并返回标量基本类型值 "abc" ,与 a 相等。
a == b; // true //null和undefined不能够被封装(boxed),Object(null)和 Object(undefined) 均返回一个常规对象。
var a = null;
var b = Object(a); // 和Object()一样
a == b; // false var c = undefined;
var d = Object(c); // 和Object()一样
c == d; // false
//NaN能够被封装为数字封装对象,但NaN不等于NaN
var e = NaN;
var f = Object(e); // 和new Number( e )一样
e == f; // false

5)假值的相等比较

假值,就是上面ToBoolean中提到的假值。

"0" == false;//true 按照2)和1)的规则
false == 0;//true 按照2)的规则
false == "";//true 按照2)和1)的规则
false == [];//true 按照4)2)1)的规则
"" == 0;//true 按照1)
"" == [];//true 按照4)的规则
0 == [];//true 按照4)1)的规则
[] == ![]// true ![]执行后的值是false

6)安全运用隐式强制类型转换

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

2.如果两边的值中有[]、0或者"" ,尽量不要使用==。

7)比较图表

dorey提供的一张在线图表

《你不知道的JavaScript》整理(六)——强制类型转换的更多相关文章

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

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

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

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

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

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

  4. Javascript基础之-强制类型转换(二)

    思考下面这个问题: console.log(+"123"); // 123 console.log(-"123"); // -123 console.log(+ ...

  5. 你不知道的JavaScript(六)Box&Unbox

    很多语言中都有Box和Unbox的概念,很多书籍把Box翻译为"装箱操作",指的是將基本数据类型包装成对象:Unbox和它相反,把对象类型转换为基本类型. 我们知道JavaScri ...

  6. javascript第六课类型转换

    1.parseint(参数): 转换为整数,即使参数中的字符串包含字母数字混合,此方法也会自动一个一个判断和转换   parseInt(参数,进制);将参数通过几进制的方式转为数字 2.parsefl ...

  7. 你不知道的JavaScript之类型

    JavaScript是一门简单易用的语言,应用广泛,同时它的语言机制又十分复杂和微妙,即使经验丰富的开发人员也需要用心学习才能真正掌握. <你不知道的JavaScript>中是这样定义类型 ...

  8. JS的强制类型转换

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

  9. javascript中强制类型转换

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

随机推荐

  1. 1.4.2.3. SETUP(Core Data 应用程序实践指南)

    初始化Core Data的三个方法: init,初始化托管对象模型.持久化存储协调器.托管对象上下文 - (id)init { ) { NSLog(@"Running %@ '%@'&quo ...

  2. 常用的.net开源项目

    Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Li ...

  3. 动软模板系列二(Model层模板)

    动软模板其实和CodeSmith的模板差不多 实现的原理是一样的,但是CodeSmith貌似只支持表生成,而且不够“国人化”,所以打算研究下动软的模板,如果熟练掌握后想必以后开发项目效率可以提高很多了 ...

  4. easyUI draggable组件使用

    easyUI draggable组件使用: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  5. nginx安装配置

    Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,由俄罗斯的程序设计师Igor Sysoev所开发,其特点是占有内存少,并发能力强 1. apache ...

  6. Jquery实现的几款漂亮的时间轴

    引言 最近项目中使用了很多前端的东西,对于我一个做后台开发的人员,这是一个很好的锻炼的机会.经过这段时间的学习,感觉前端的东西太多了,太强大了,做出来的东西太炫酷了.现在有很多开源的前端框架,做的都非 ...

  7. [TPYBoard-Micropython之会python就能做硬件 2] 利用micropython控制NOKIA 5110屏

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.本次实验所需器材 1.TPYboard V102板  一块 2.DS3231 ...

  8. web开发的性能准则(减少页面加载时间方面)

    准则(概述) 减少 HTTP 请求 使用CDN加速 避免空的src或href属性值 增加过期头 启GZIP压缩 把css文件放到头部 把javascript放到尾部 避免使用css表达式 删除不使用的 ...

  9. ArcGIS Pro 简明教程(3)数据编辑

    ArcGIS Pro 简明教程(3)数据编辑 by 李远祥 数据编辑是GIS中最常用的功能之一,ArcGIS Pro在GIS数据编辑上使用习惯有一定的改变,因此,本章可以重点看看一些编辑工具的使用和使 ...

  10. 关于JavaScript中的编码和解码函数

    js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent 1 ...