复杂数据类型如何转成简单数据类型?一文带你搞懂

267 阅读2分钟

在上一篇文章我们介绍了JS中简单数据类型之间是如何转换的,这篇文章将着重介绍复杂数据类型和简单数据类型之间的转换规则。

简单数据类型之间是如何转换的?一文带你搞懂

在JavaScript中,数据类型分为简单(原始)数据类型和复杂(引用)数据类型。简单数据类型包括:undefined, null, boolean, number,symbol,bigintstring。复杂数据类型则主要是指对象(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

今天的分享就到这,喜欢的就点个赞再走吧