强制类型转换
(1)布尔值转换
0、-0、NaN、undefined、null、""(空字符串)这几种情况转换布尔类型会得到 false,除了这几种情况外所有数据类型都会得到 true。
(2)数值类型转换
由以下三种强制类型转换:
-
Number():属于严格转换
-
当全部为数字或者解析全部为数字时才会正确转换。
-
当出现非数字或者空格时返回NaN,
-
当遇到空字符串、null或者布尔类型false时返回0,
-
当遇到布尔类型true时返回1,
-
当遇到undefined时返回NaN。
isNaN(): 可以用于判断传入值是否为非有效数字,非有效数字返回true,有效数字返回false。
Number.isNaN(): 只有当传入的值未NaN时, 才返回true, 否则返回false
console.log(Number(123)); //123
console.log(Number('123')); //123
console.log(Number('123aa')); //NaN
console.log(Number('')); //0
console.log(Number([])); //0
console.log(Number(null)); //0
console.log(Number(false)); //0
console.log(Number(true)); //1
console.log(Number(undefined)); //NaN
- parseInt():非严格转换
该方法可以把其他数据类型转换为整数,只取整数部分,当遇到以非数字开头的数据类型时,返回NaN。
console.log(parseInt(123)); //123
console.log(parseInt(123.23)); //123
console.log(parseInt('123.23')); //123
console.log(parseInt('123aa')); //123
console.log(parseInt('.123aa')); //NaN
console.log(parseInt('abc')); //NaN
console.log(parseInt('abc123')); //NaN
-
parseFloat():与parseInt转换机制一样, 只不过该方法是保留浮点数。
console.log(parseFloat(123)); //123 console.log(parseFloat(123.23)); //123.23 console.log(parseFloat('123.23')); //123.23 console.log(parseFloat('123aa')); //123 console.log(parseFloat('.123aa')); //0.123 console.log(parseFloat('ab123.23aa')); //NaN console.log(parseFloat('abc')); //NaN
(3)字符串转化
- toString()
几乎每个类型的值都有的toString()。
但是有一点需要注意的是null和undefined值没有这个方法。
var colors = ['red','blue','green'];
var num = 123;
var found = true;
console.log(colors.toString()); //"red,blue,green"
console.log(num.toString()); //"123"
console.log(found.toString()); //"true"
- String()
这个函数可以将任何值转换为字符串
var colors = ['red','blue','green'];
var num = 123;
var found = true;
console.log(String(colors)); // "red,blue,green"
console.log(String(num)); // "123"
console.log(String(found)); // "true"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
valueOf和toString的区别
基本上所有的JavaScript数据类型都有valueOf(),toString()方法,null和undefined除外,这两个方法解决了JavaScript值运算和显示的问题。
valueOf():会把数据类型转换成原始类型,也就是说原来是什么类型,转换后还是什么类型,日期类型除外。
toString():会把数据类型转换成string类型,也就是说不管原来是什么类型,转换后一律是string类型。
使用场景
- valueOf()偏向于运算,toString()偏向于显示
- 对象转换时,优先调用toString()
- 强转字符串的情况下,优先调用toString()方法;强转数字的情况下优先调用valueOf()
- 正常情况下,优先调用toString()
- 在有运算操作符的情况下valueOf()的优先级高于toString(),这里需要注意的是当调用valueOf()方法无法运算后还是会再调用toString()方法
隐式转换规则
- 转为number类型:
+-*/++--(算数运算符)><>=<===!====!==(比较运算符); - 转为string类型:
+不仅是算术运算符,还可以做为字符串连接符把数据转换成string类型; - 转为boolean类型:
!(逻辑非运算符)
+运算符的隐式转换
+两边有一边是字符串,那这个**+**就是字符串连接符,它会把其他数据类型调用String()方法转成字符串然后拼接;
+做为算术运算符会把其他数据类型调用Number()转成数字然后做加法运算;
console.log(1 + true); //2
console.log(1 + "true"); //"1true"
console.log(1 + undefined); //NaN
console.log(1 + null); //1
// null转化为0 undefined转化为NaN
比较(关系)运算符的隐式转化
比较运算符会把其他数据类型转换number数据类型后再比较。
-
当一边是字符串的时候,会调用
Number()方法把字符串转换成数字在进行比较; -
当关系运算符两边都是字符串的时候,此时同时转成number然后比较关系;
重点:此时并不是按照Number()的形式转成数字,而是按照字符串对应的unicode编码来转成数字,使用 字符串.charCodeAt(字符下标,默认为0) 方法可以查看字符的unicode编码。
-
当布尔值和数字比较时,会把布尔值通过
Number()转成数字再进行比较,true转成1,false转成0; -
当字符串和布尔值比较时,会把字符串和布尔值都通过
Number()转成数字再进行比较。
注:null == undefined //true ; NaN和谁都不相等,包括他自己.
console.log("2" > 10); //false
console.log("a" > 10); //false
console.log(10 > "a"); //false
console.log(Number("a")); //NaN
console.log("2" > "10"); //true '2'.charCodeAt() > '10'.charCodeAt() = 50 > 49 = true
console.log(false == 0); //true
console.log(false == ""); //true
console.log(Number(false)); //0
console.log(NaN == NaN); //false
console.log(undefined == null); //true
console.log(Number(NaN)); //NaN
console.log(Number(undefined)); //NaN
console.log(Number(null)) //0
复杂数据类型的隐式转换
会将复杂数据类型转化为number数据类型, 再进行比较。
- 先使用
valueOf()方法获取原始值,如果原始值不是number数据类型,则使用toString()方法转成string; - 再通过
Number()方法装成number数据类型
注意:空数组的toString()方法会得到空字符串,而空对象的toString()方法会得到字符串[object Object]
console.log([1,2] == '1,2'); //true 先将左边数组转成string,然后右边也是string则转成unicode编码运算
console.log([] == 0);//true 默认通过同String()转成空字符串,再通过Number("")转成0
var a = {};
console.log(a == 0); //false
console.log(a.valueOf().toString()); //"[object Object]"
逻辑非隐式转换和比较运算符隐式转换
0、-0、NaN、undefined、null、""(空字符串)这几种情况转换布尔类型会得到 false,除了这几种情况外所有数据类型都会得到 **true。**
以下都是:
- **先将左右两边的值通过.valueOf().toString()转化为字符串, **
- 然后通过Number("值")转化为数字之后进行对比。
//大坑
console.log ( [] == 0 ); //true
console.log ( ! [] == 0 ); //true
//神坑
console.log ( [] == ! [] ); //true
console.log ( [] == [] ); //false
//史诗级坑
console.log({} == !{}); //false
console.log({} == {}); //false
[].valueOf().toString()得到空字符串Number("") == 0成立
![] 与 0比较:
- 逻辑非优先级高于关系运算符
![] = false(空数组转布尔得到true,然后取反得到false) false == 0成立
[] 与 ![]比较:
[].valueOf().toString()得到空字符串 ""![] = falseNumber("") == Number(false)成立 都是0
[] 与 []比较:
引用类型数据存在堆内存中,栈内存中存储的是地址,所以他们的结果是false
{} 与 !{}比较:
{}.valueOf().toString()得到字符串'[object Object]'!{} = falseNumber('[object Object]') == Number(false)不成立,因为转换到最后 是NaN和0比较,所以结果为false
{} 与 {}比较:
引用类型数据存在堆内存中,栈内存中存储的是地址,所以他们的结果是false
参考文章:js数据类型转化
常用的几种运算符各运算符优先级:
算术运算符:+ - * / ++ --
比较运算符: > < >= <= == != === !==
逻辑运算符:&& || !
赋值运算符:= += -= *= /=
算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符