文章目录
1、显式类型转换
JS中有三种数据类型转换,转换为数字、字符串、boolean值。
(1) Number():
1. undefined : NaN
2. null : 0
3. 布尔值 : true为1,false为0
4. 字符串 : <1>. 空字符串,空格字符串转为0
<2>. 非空字符串,并且内容为纯数字(包含进制与科学表示法)转成对应的数字
<3>. 其余都式NaN
5. 数字 : 原来的数字
6. 对象 : <1>.对象、函数转为NaN
<2>.空数组转为0,数组里只有一个数据并且这个数据能转成数字,则转成对应的数字,其它都转成NaN
例:
console.log(
Number(undefined), //NaN
Number(null), //0
Number(true), //1
Number(false), //0
Number(''), //0
Number(' '), //0
Number('12'), //12
Number('012'), //12
Number('0xff90'), //65424
Number('5e5'), //500000
Number('k'), //NaN
Number({}), //NaN
Number([]), //0
Number(function () { }), //NaN
Number(['']), //0
Number([2]), //2
Number(['2']), //2
Number([2,3]), //NaN
)
(2) String():
1. 基本数据类型、null、undefined的结果就是给数据加上引号变成字符串
2. 对象 : <1>. 数组的结果为把所有中括号去掉,外面加个引号
<2>. 对象的结果为'[object Object]'
<3>. 函数的结果为在函数整体外面加个引号
例
console.log(
String(null), //'null'
String([1,[2]]), //'1,2'
String(function() {}), //'function(){}'
String({}), //'[object Object]'
)
(3) Bollean():
1. undefined : false
2. null : false
3. 数字 : +0、-0、NaN转布尔值的结果为false,其它的转布尔值的结果为true
4. 布尔值 : 转为对应的值
5. 字符串 : 空字符串转布尔值的结果为false,其它(包括空格字符串)的都转成true
6. 对象 :转布尔值都是true
例
console.log(
Boolean(undefined), //false
Boolean(null), //false
Boolean(+0), //false
Boolean(-0), //false
Boolean(NaN), //false
Boolean(''), //false
Boolean(' '), //true
Boolean('0'), //true
Boolean({}), //true
Boolean([]), //true
Boolean(function(){}), //true
)
(4) 转换原理:valueOf()、toString()
主要靠两个方法:
valueOf:返回对象对应的原始值
toString:返回对象的字符串的表现形式
1. 数字、字符串、布尔值 :
valueOf 数据本身(原始值形式)
toString 数据转成字符串的形式
2. 数组:
valueOf 数据本身(对象形式)
toString 去掉中括号,外面加个引号(本质为调用数组join(',')后的结果)
3. 函数:
valueOf 数据本身(对象形式)
toString 在数据外面加了个引号
4. 对象:
valueOf 数据本身(对象形式)
toString "[object Object]"
Number方法
1、调用对象的valueOf方法。如果返回原始类型的值,再使用Number函数,不再进行后续步骤
2、如果valueOf方法返回的还是对象,则调用toString方法
3、如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤
4、如果toString方法后返回的是还是对象,就报错(一般不会出现)
String参数为对象的转换原理
1、调用对象的toString方法。如果返回原始类型的值,再使用String函数,不再进行后续步骤
2、如果toString方法返回的还是对象,再调用对象的valueOf方法
3、如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤
4、如果valueOf方法返回的是还是对象,就报错(一般不会出现)
2、隐式类型转换
隐式类型转换出现场景:
- 不同类型的数据间运算、比较
- 对非布尔值类型的数据求布尔值
- 条件语句的括号里
(1) 转数字:
隐式转数字出现的场景:
- 数学运算符(+ - * / %),都会转成数字类型
注意(+特殊):一般加号运算符两侧数据会转换成数字类型进行加法运算,
但是,若出现字符串或对象类型数据,则会把两侧数据转换成字符串进行拼接 - 一元±(正负操作符)后的数据
- 某些比较运算符
例:
console.log(
// 转Number
1 + undefined, //1+NaN=NaN
1 + null, //1+0=1
null + undefined, //0+NaN=NaN
true + false, //1+0=1
3 + '6', //'36'
// 转String
2 + [], //String(2)+String([])='2'+''='2'
2 + { a: 12 }, //String(2)+String({a:12})='2[object object]'
[] + {}, //String([])+String({})=''+'[object,Object]'='[object object]'
{} + [], //'[object object]'
3 + {}, //'3[object object]'
{} + 3, //'[object object]3'
)
(2) 转字符串:
隐式转字符串出现场景:
- 有字符串的加法运算
- 有对象的加法运算
- 某些比较运算符
- 调用alert、document.write方法
console.log(
'1'+2, //'12'
'1'+'c', //'1c'
'1'+undefined , //'1undefined'
'1'+[], //'1'
)
console.log(
2+[2,3], //'2'+'2,3'='22,3'
2+function(){}, //'2'+'function(){}'='2function(){}'
1+[], //'1'+''='1'
1+{}, //'1'+'[object Object]'='1[object Object]'
)
console.log(
[]+{}, //''+'[object Object]'='[object Object]'
{}+null, //'[object Object]'+'null'=[object Object]null
[]+undefined, //''+'undefined'='undefined'
)
alert({a:12}); //String({a:12})='[object Object]'
alert(function(){}); //String(function (){})='function(){}'
document.write({b:1}); //String({b:1}) = '[object Object]'
console.log(++[[]][+[]]+[+[]]); //'10'
/*
++[[]][+[]]+[+[]]
++[[]][+[]] + [+[]]
++[[]][+[]] + [+[]]
++[[]][0] + [+[]]
++[[]][0] + [+[]]
++[] + [+[]]
++0 + [+[]]
1 + [+[]]
1 + [0]
'1' '0'
*/
(3) 转布尔值:
隐式转布尔值出现场景:
- 取反运算
- 三目运算符
- 条件语句的小括号里
- 逻辑运算符
var data=[10,'kaivon',true,null,undefined,function(){},{a:12},[0,1]];
for(var i=0;i<data.length;i++){
console.log(!data[i]);
console.log(!!data[i]);
console.log(data[i]?20:30);
if(data[i]){
console.log(1);
}
}
var a = [0];
//Boolean([0])=true
if([0]){
console.log(a==true);
// 执行 true == true //false
}else{
console.log('cc')
}
3、大小比较
- 如果比较两边有字符串,那会对比它们各自对应的Unicode码值
- 如果比较两边都为原始类型数据,那把所有数据转成数字进行对比;NaN与任何数据对比都是false
- 有对象数据的比较,先调用valueOf再调用toString方法,然后看另一数据的类型,如果另一个数据为字符串,则转为字符串对比,如果另一个数据为数字则转为数字对比
总结 :
- 字符串与字符串、字符串与对象、对象与对象比较时,都会转成字符串,然后对比Unicode码值
- 其它类型数据,转成数字对比
例:
console.log(
'A' > 'a', //false 65 > 97
'大' > '小' //false 22823 > 23567
)
console.log(
true > false, //true 1>0
'k' > 5, //false NaN>5 NaN
undefined > false, //false NaN>0 NaN
null >= '', //true 0>=0
null >= ' ' //true 0>=0
);
console.log(
[] > 0, //false 0>0 转数字比较
{} > 1, //false NaN>1 NaN 转数字比较
{} > true, //false NaN>1 NaN 转数字比较
{} > '/', //true [object Object] '['>'/' = 91>47 转字符串比较
{} > '[', //true [object Object] '['>'[' = 91=91 'o'>''=111> 转字符串比较
);
console.log(
{ a: 12 } < function () { },
// true 转成字符串比
// '[object Object]'<'function(){}'
// '['<'f' = 91<102
);
console.log(
[]>=0, //0>=0 true
null==false, //false
[1]==true, // '1'==true 1==1 true
[1,'a',3]=='1,a,3', //'1,a,3' == '1,a,3' true
undefined>false, // NaN>0 false
[]==null, //false
[2]>[11], //'2'>'11' = 50>49 true
2==true, // 2==1 false
[undefined] == undefined, //'undefined'==undefined NaN==NaN false
'true'==true, // NaN == 1 false
)
4、相等比较
- 不同类型的原始类型数据,把所有的数据转成数字后进行对比
- null与undefined除了它们自己与自己、自己与对方相等,与其它的任何数据都不相等
- 对象与原始类型数据比较时,把对象转成原始值,再进行比较
- 对象与对象类型比较时,比较的是他们的引用地址,除非引用地址相同,否则都不相等
总结 :
- 原始类型对比,转成数字对比
- 对象类型对比,把对象转成字符串,然后看对方的类型,如果不一样,都转成数字对比。对象与对象比较,比较引用地址
- null与undefined,自己与自己、自己与对方相等。与其它任何数据都不相等
例
//原始值比较 转数字
console.log(
12 == '12', //true 12==12
0 == '', //true 0==0
1 == true, //true 1==1
2 == false, //false 2==0
'true' == true, //false NaN==1
' ' == false, //true //0==0
);
//只有 undefined == null
console.log(
undefined == 0, //false
undefined == '', //false
undefined == false, //false
undefined == undefined, //true
null == 0, //false
null == '', //false
null == false, //false
null == undefined, //true
null == null //true
);
//先转成字符串 若对方不是字符串则都转成数字比较
console.log(
[1] == 1, //true '1'==1 1==1
[] == 0, //true ''==0 0==0
[1] == true, //true '1'==true 1==1
[1, 'a', 3] == '1,a,3', //true '1,a,3'=='1,a,3'
[] == undefined, //false
{ a: 1 } == 1, //false '[object Object]'==1 NaN==1
[null] == null, //false
);
//对象与对象比较引用地址
console.log(
[] == [], //false
{} == {}, //false
);
var fn1 = function () {
return 1;
}
var fn2 = function () {
return 1;
}
var fn3 = fn1;
console.log(fn1 == fn2); //false
console.log(fn1 == fn3); //true
console.log(
'true' == true, //false NaN == 1
undefined == false, //false
null == 0, //false
[] == 0, //true ''==0 0==0
{ a: 1 } == { a: 1 }, //false
)
5、逻辑运算符
&&:全真则为真 返回第一个为false的表达式
||:一真则为真 返回第一个为true 的表达式
//&&的返回值:左面为真返回右面的值,左面为假返回左面的值
console.log('cc' && 1 + 2) //3
console.log(0 && 2 + 2) //0
console.log(![] && '你好!')
//!Boolan([]) => !true => false
//false
var n1 = 1;
n1 - 1 && (n1 += 5);
console.log(n1);
//返回 n1-1为 false
//n1=1
function fn1() {
console.log('车光青');
}
n1 == 1 && fn1(); //fn1会执行
// if(n1=1){
// fn1();
// }
console.log(true && 'cc' && (2 - 2) && 'abc' && true) //0
console.log(true && 'cc' && (3 - 2) && 'abc' && true && (2 + 2)) //4
// ||的返回值:一碰到真的就返回
console.log('cc' || 2 + 1) //'cc'
var n2 = 1;
n2 - 1 || (n2 += 5);
console.log(n2); //6
function fn3(text){
text=text || 'cc';
console.log(text)
}
fn3(); //'cc'
fn3('车车') //'车车'
6、逗号运算符
逗号运算符(从左往右执行表达式,返回最后表达式的结果)
console.log(1, 2, 3); //1,2,3 ,作用是参数分隔
console.log((1, 2, 3)); //3 ,运算符(从左往右执行表达式,返回最后表达式的结果)
alert(1,2,3); //1 alert函数只能接收一个参数
alert((1,2,3)); //3 (1,2,3)表达式 返回最后一个
var a = 10;
var b = (a++ , 20, 30);
console.log(a, b); //11 30
//var a=10,b=20;
a += 3, b += 4;
console.log(a, b); //14 34
for (var i = 0, j = 0, k; i < 6, j < 10; i++ , j++) {
//i<6,j < 10; 这个条件会返回j<10 所以i、j都循环10次
k = j + i; //9+9
console.log( j, i); // 9 9
}
console.log(k); //18
var a = 10, b = 20;
function fn() {
return a++ , b++ , 10;
// return 10
}
console.log(a, b, fn()); // 10 20 10
let c = fn();
console.log(a, b, c) //12 22 10
//执行了两次fn函数
{
let a = 10;
let b = 20;
//交换a b 的值
// 1>.
// let c;
// c = a;
// a = b;
// b = c;
// console.log(a,b); //20 10 */
// 2>.
// a = a+b; //30
// b = a - b; //10 = 30-b
// a = a - b; //20 = 30 -10
// console.log(a,b); //20 10
// 3>.
a = [b][b = a, 0];
//a=[20][b=10,0];
//a=[20][0]; //数组取值
//a=20;
// 逗号运算符 从左往右执行 返回最后一个值
console.log(a,b); //20 10
// 3>.
[b,a] = [a,b]
// [b,a] = [10,20]
}