你不知道的JS(中篇)——四、强制类型转换

强制类型转换:将值从某一个类型转换成另一种类型;

准确来说可以分为显式类型转换和隐式类型转换

1、抽象值操作:ToNumber、ToString、ToBoolean
(1)toString(): 非字符串转换成字符串;

①对于数组而言,它的 toString ( ) 方法,返回的值默认是以逗号 “,” 来连接;

let arr = [1,3,2,4];

arr.toString(); //"1,3,2,4"

②对于JSON.stringify(),对于传入的值处理如下:

JSON.stringify(42); //"42"

JSON.stringify("42"); //""42"",包了两层引号

JSON.stringify(null); //"null"

JSON.stringify(true); //"true"

JSON.stringify(undefined); //undefined

JSON.stringify(function () { }; //undefined

如果传入的参数是对象或者数组,对象中的undefined、function、symbol会被忽略,而数组中则会用null来代替(为了占位)

let obj = {
    name: undefined,
    age: 25,
    action: function () {//do some things;},
    country: Symbol("China")
};

let arr = [ 1, undefined, function(){}, Symbol("foo")];

let obj1 = JSON.stringify(obj); //{"age":25} 

let arr1 = JSON.stringify(arr); //[1, null,null,null ]

另外,JSON.stringify(a, replacer, space) 还有两个可选参数 replacer 和 space;
replace 可以是数组或者函数。正如他的名字所言,可以进行过滤。数组的项就是 a 的属性名,函数所传入的参数是 a 的键名和值名;
sapce可以是正整数或者字符串,控制解析后的缩进,传入正整数就是缩进 n 行,传入字符串就取字符串的前几位(最多取十位)作为缩进字符;

let obj = {
    name: "troyes",
    age: 25,
    job: "webDeveloper",
    country: "China"
};
let out1 = JSON.stringify(obj,
                        ["name", "age", "job", "country"],
                        "ddddddd");

let out2 = JSON.stringify(obj,
                        function (key, value) {return value;},
                        "ddddddd");

let out3 = JSON.stringify(obj,
                        function (key, value) {return value;},
                        5);

console.log(out1, out2); 
/**
两个
{
ddddddd"name": "troyes",
ddddddd"age": 25,
ddddddd"job": "webDeveloper",
ddddddd"country": "China"
}
**/


console.log(out3); 
/**
//前面五个空格
{
     "name": "troyes",
     "age": 25,
     "job": "webDeveloper",
     "country": "China"
}
**/
(2)真假值: undefined、null、+0、-0、NaN、false、” ” 都是假值;

另外,只有在IE中,document.all 才是真值,可以用来做兼容判断;

!!!!!用到 “ == ” 操作符的时候,两边千万不要有 true、false、“”、0、[] ,用了就是找罪受!!!你敢想Boolean([])居然是true???
let arr = [undefined, null, +0, -0, NaN, false, ""];
let out = [];
arr.forEach((item)=>{
    out.push(Boolean(item));
});
console.log(out); 
//[ false, false, false, false, false, false, false ]
//注意:arr的最后一项是空字符串"",连空格都不能加,否则就是真值
2、显式类型转换
(1)字符串和数字之间的显式类型转换

string →number:Number(str) ;
number → string:String() 还有 num.toString()
示例代码:

Number(""); //0
String(43); //"43"
let a= 43;
a.toString(); //"43"

①日期转换成数字:一般应用于时间戳,利用了加号运算符“+”;

let a = new Date("2018-09-04T06:03:05.113Z");
+a; //1536040985113

当然还是走寻常路更加利于代码阅读:
获得当前时间戳,用Date.now() ;
获得指定时间的时间戳,用new Date(...).getTime() ;

Date.now(); //1536041389150
new Date("2018-09-04T06:03:05.113Z").getTime(); //1536040985113

②显式解析 数字字符串:利用parseInt()parseFloat()
解析和转换有什么分别?
解析:待解析的字符串可以有非数字以外的字符;
转换:利用Number()来转换则会比较苛刻,如果存在非数字字符,返回的结果会是NaN;

let a = "123ddd";

console.log(parseInt(a), Number(a)); //123, NaN

另外,使用的时候第二个参数最好要加上:parseInt(str, 10)
如果要支持到ES5之前,要这样写才不会出现莫名奇妙的结果;

(2)将其他类型值转换成布尔值:用Boolean() 和 !!;
let arr = ["123ddd", 124, {name:"dddd",age: 34}, [1,3,4], function () {console.log("gggg");}];

let out1 = [];
let out2 = [];
arr.forEach((item)=>{
    out1.push(Boolean(item));
    out2.push(!!item);
});
console.log(out1, out2, out1 == out2);
//[ true, true, true, true, true ] [ true, true, true, true, true ] false
3、隐式强制类型转换
(1)关于number的隐式强制类型转换

number → str:利用加号或者减号,如num + “” ,num-“”
→ number: 利用加减乘除这些运算符,因为在这些运算符工作的时候,会先调用toString(),然后再调用Number()

let a = 123;
let b = "123";
let c= [3];
let d = [2];
a+""; //"123"
b-0; //123
c-d; //1
(2)布尔值转换成数字: 还是利用加减运算符:
let a = true;
a - 0 = 1;
(3)其他类型值被隐式强制转换成布尔值:

(1)三元运算符: (…)?(…):(…); 第一个括号里的表达式
(2)|| 和 && 操作数选择器中,左边的操作数;
拓展: || 左边操作数是真就返回左边的操作数,否则返回右边操作数; && 则刚好跟 || 相反;
(3)for(){} 、 whlile(){}、do{}while() 这三个里面需要用到的判断表达式;
(4)if(){} 条件判断表达式;
在这几种情况之中,都存在隐式强制转换成布尔值;

(4) 符号Symbol的强制类型转换:

这个ES6 新增的鬼东西,不能进行隐式强制类型转换,但是却可以显式强制类型转换,你说奇不奇怪?

let a = Symbol("name is troyes");
let b = a.toString();
let c = String(a);
// let d = a + ""; //TypeError
console.log(a,b,c); //Symbol(name is troyes) 'Symbol(name is troyes)' 'Symbol(name is troyes)'
4、让人头晕的宽松相等(==)和严格相等(===)

两者的不同之处在于,宽松相等允许进行强制类型转换,而严格相等不允许;
也就是说,宽松相等不要求类型相等,只要值相等就会返回true; 而严格相等就要求类型和值都要相等才返回true;

(1)NaN跟谁都不相等,甚至跟NaN也不相等;+0和-0严格相等;
NaN == NaN; //false 
+0 === -0; //true
(2)当布尔值和其他类型的值进行比较的时候,布尔值会先经过Number()变成数字,在进行比较;

所以尽量避免直接使用布尔值和其他类型值来进行比较

let a = "35";
let b = true;
let c = false;
a==b; //false, 相当于 35 === 1
a==c; //false, 相当于 35 === 0
(3)null 和 undefined 两者在比较中的情况:

这两个比较奇特,除了跟本身严格相等,他们之间还宽松相等;但是他们跟其他值比较都是false,譬如:false、0、” ” 等等;

猜你喜欢

转载自blog.csdn.net/qq_39798135/article/details/82357177