在上一篇文章我们介绍了JS中简单数据类型之间是如何转换的,这篇文章将着重介绍复杂数据类型和简单数据类型之间的转换规则。
在JavaScript中,数据类型分为简单(原始)数据类型和复杂(引用)数据类型。简单数据类型包括:undefined, null, boolean, number,symbol,bigint 和 string。复杂数据类型则主要是指对象(object),其中包括数组(Array)、函数(Function)、日期(Date)等。
1. object -> boolean
所有对象在转换为布尔值时都会变成true,除了空对象可能会根据上下文不同而有所不同。
console.log(Boolean(new Boolean(false))) // true
console.log(Boolean({})) // true
console.log(Boolean([])) // true
2. object -> string
object先去原型链中或自身的方法中找tostring方法,如果没找到或返回的值为NaN则再找valueof方法,找不到或仍为NaN则返回TypeError,顺序为 toString -> valueOf -> TypeError
console.log(({a:1,b:2}).toString()); // '[object Object]'
console.log(JSON.stringify({a:1,b:2})) // '{"a":1,"b":2}'
console.log(Object.prototype.toString.call({a:1,b:2})) // '[object Object]'
console.log(String({a:1,b:2})) // '[object Object]'
console.log(String[1,2]); // '1,2'
console.log((() => {}).toString()); // 'function () {}'
console.log(String(new Date())); // 'Sat Mar 10 2018 10:19:57 GMT+0800 (中国标准时间)'
3. object -> number
object先去原型链中或自身的方法中找valueof方法,如果没找到或返回的值为NaN则再找tostring方法,找不到或仍为NaN则返回TypeError,顺序为 valueOf -> toString -> TypeError
console.log(Number({ key: "value" })); // NaN
let obj = {
valueOf: function() { return 42; }
};
console.log(Number(obj)); // 42
console.log(Number([1])); // 1
console.log(Number([])); // 0
console.log(Number([1, 2])); // NaN
console.log(Number(new Date('2024-01-01'))); // 返回对应的毫秒数
console.log(Number(new Date('invalid-date'))); // NaN
4. object -> number|string
总结一句就是 toPrimitive 是使命
// Object => Primitive
let specialObj = {
valueOf:function(){
console.log('calling valueof')
return 123;
},
toString:function(){
console.log('calling toString')
return '456';
}
}
console.log(Number(specialObj)); // 123
console.log(String(specialObj)); // 456
let objectWithoutPrimitiveValueOf = {
valueOf:function(){
console.log('calling valueof')
return this;
},
toString:function(){
console.log('calling toString')
return this;
}
}
try{
console.log(Number(objectWithoutPrimitiveValueOf));}
catch(e){
console.log(e); // TypeError: Cannot convert object to primitive value
}
5. 总结
- 转Boolean:基本上所有的复杂数据类型都会显示的转换为true
- 转string:toString -> valueOf -> TypeError
- 转number:valueOf -> toString -> TypeError
今天的分享就到这,喜欢的就点个赞再走吧