强制类型转换
强制类型转换是显式或隐式的将一种类型转换为另一种类型。
一、ToString
ToString:仅代表非字符串到字符串的强制类型转换。
ToString 转换规则:
-
基本类型值 字符串化规则:
null -> “null”、undefined -> “undefined”、true -> “true”。
不安全值:undefined、function、symbol 返回 undefined。 -
对象本身 或已经 封装成对象 进行强制类型转换规则:执行抽象操作 ToPrimitive 。
(1)首先检查是否有 toString() 方法,如果有并且返回基本类型值,就使用该值进行强制类型转换。
(2)如果没有 toString() 方法,则使用 valueOf() 的返回值(如果存在)来进行强制类型转换。
(3)如果 toString() 和 valueOf() 均不返回基本类型值,会产生 TypeError 错误。若是不安全值在对象中:JSON.stringify(obj) 会自动忽略该不安全值。
若是不安全值在数组中:JSON.stringify(array) 会在该值位置返回 null 占位。
显式(非字符串转字符串)强制类型转换
-
String() :原生函数转换为字符串基本类型。
-
Object.prototype.toString():普通对象,若没有自行定义 toString() 方法属性,则返回内部属性 [[Class]] 的值。
-
JSON.stringify():JSON转字符串。
1、字符串、数字、布尔值和 null 的 JSON.stringify(…) 规则与 ToString 基本相同。
2、如果传递给 JSON.stringify(…) 的对象中定义了 toJSON() 方法,那该方法会在字符串化前调用,以便将对象转换为安全的 JSON 值(将非法 JSON 值对象转换为安全的 JSON 值)。 -
toString():基本类型值无属性,使用 .toString() 会自动封装成对象。
隐式强制转换类型
-
a + " ":隐式转换 a 为字符串(不遵从ToString 抽象规则)。
如果 a 是对象,a + " " 会对 a 调用 valueOf() 方法,然后通过 ToString 抽象操作将返回值转换为字符串,而 String(a) 则是直接调用 ToString()。注意:
1、 + 运算符能用于数字加法,也能用于字符串拼接。
判断依据:如果 + 的其中一个操作数是字符串(或是对象和数组通过 ToString 规则得到的字符串)则执行字符串拼接;否则执行数字加法。
2、+ 的另一个用途:将日期(Date)对象强制类型转换为数字。
显式时间戳的另一方法:new Date().getTime()
二、ToNumber
ToNumber:仅代表非数字类型转换为数字类型。
ToNumber 转换规则:
-
基本类型值 转换:
true -> 1、false -> 0、undefined -> NaN、null -> 0。
处理失败时返回 NaN ;对以0开头的十六进制数并不按十六进制处理,而是十进制。 -
对象 或 封装对象 强制类型转换规则:执行抽象操作 ToPrimitive 。
(1)首先检查是否有 valueOf() 方法,如果有并且返回基本类型值,就使用该值进行强制类型转换。
(2)如果没有 valueOf() 方法,则使用 toString() 的返回值(如果存在)来进行强制类型转换。
(3)如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。
显式强制类型转换
-
Number() :原生函数转换为数字基本类型(不允许字符串中出现非数字字符,否则失败返回 NaN)。
-
一元运算( + 或 - ) 显式强制类型转换。
var a = "3.14"; var b = +a; console.log(b); //3.14 console.log(typeof b); //number a - 0; a * 1; a / 1; sum += arguments[i]; //布尔值转数字隐式强制类型转换
关于运算符拓展:
(1)++、– 是递增递减运算符。
(2)- - 也可以反转符号位(中间的空格不能丢)。
尽量不要将一元运算符( + 或 - )和其他运算符放在一起使用。
(3)d = +c( d =+ c)和 d += c 两者不同。
(4)一元运算符( + 或 - )紧挨着 ++ 和 – 也容易混淆。
eg: a +++b、a+ ++b、a+ + +b。 -
字位运算符( | 或 ~ )
ToInt32:首先执行 ToNumber 强制类型转换,比如“123”会先转换为 123 ,然后再执行 ToInt32:。
(1) 0 | __ :仅执行 ToInt32 转换
var a = "3" console.log(0|a); //3 console.log(typeof a); //number //个别特殊情况以32位格式呈现 0|-0; //0 0|NaN; //0 0|Infinity; //0 0|-Infinity; //0
(2)~ :首先将值强制类型转换为32位数字,再执行字位操作“非”(对每一位进行反转)。
~X = -(X+1)
typeof (~X) = number(3)~~ :截除数字值的小数部分
第一个 ~ 执行 ToInt32 并反转字位;第二个 ~ 再进行一次字位反转,最终返回原值,如同只执行了 ToInt32
~~ -49.6; //-49
-
解析数字字符串,返回结果是数字(只针对 字符串值 )。
parseInt(…):第一个参数为字符串值,第二个参数为基数(默认为十进制)。
允许字符串中出现非数字字符,解析从左到右,遇到非数字字符串就停止。parseFloat(…):解析字符串中的浮点数。
三、ToBoolean
ToBoolean:仅代表非布尔值转换为布尔值。
ToBoolean转换规则:
- 假值(falsy value)
undefined、null、false、+0 、-0 、NaN、" " -> false。 - 假值对象(falsy object)
假值对象与普通对象无二致,但转换结果为 false。
如: document.all(包含假值的对象不是假值对象,仍返回 true) - 真值(truthy value)
除假值以外的值都是真值。
显式强制类型转换
-
Boolean():原生函数转换为布尔值基本类型。
-
一元运算符 !:显式地将值强制类型转换为布尔值,同时反转(真转假,假转真)。
!!:强制类型转换为布尔值,反转再反转,最终反转回原值。var a = "o"; console.log(!!a); //true console.log(typeof !!a); //boolean
-
由于 ~X = -(X+1) 能够得到 0 的 X 值为 -1,即当 X = -1 时, ~X会得到假值,其他情况返回真值。
所以 ~ 和 indexOf() 一起可以将结果强制类型转换为真假值。
indexOf() 查询结果存在就返回所在位置,否则返回-1。var a = "Hello,world"; ~a.indexOf("lo"); //-4 -> 真值 ~a.indexOf("ol"); //0 -> 假值
隐式强制类型转换
- if(…):条件判断表达式。
- for(… ; … ; …) :条件判断表达式。
- while(…) 和 do…while(…) 循环中的条件判断表达式。
- ? : :中的条件判断表达式
- 逻辑运算符 ||(或) 和 &&(与) 左边的操作数作为条件判断表达式。
- ?? :nullish 合并操作符,该操作符允许我们分配默认值,同时忽略像0和空字符串这样的假值
- ??= :逻辑 nullish 赋值操作符,只有当前值为 null 或 undefined 时,此赋值运算符才会分配新值。
- ?. :链接操作符,允许开发人员读取深度嵌套在一个对象链中的属性值,而不必沿途显式验证每个引用。当引用为 null 时,表达式停止计算并返回 undefined