在每个对象中,都会继承两个方法:toString和valueOf
toString
顾名思义,toString就是将一个对象转化为字符串类型,默认的toString方法会输出以下结果:
类型 | 值 |
---|---|
原始数据类型 | 该咋样还是咋样,不过类型都变成了字符串类型 |
function | 输出定义时的函数表达式(如function test (){ }) |
Object | [object Object],[object Array]等等 |
其中,js中对其内置对象大多都重新定义了toString方法,
如Array对象的toString方法
相当于
arr.join(',')
还有Date对象的toString
会输出当前时间的描述;
valueOf
valueOf的默认值是获取到这个对象的原始值,比如
而js中对部分的内置对象有重新定义valueOf方法
比如Date对象,就返回了1920.01.01到至今的毫秒数
toString Vs valueOf
上面对toString和valueOf做了大致的说明,我们知道,js是一门弱类型语言,有一个很鲜明的特点在于,不同类型的数据可以互相进行比较运算算。而在这个运算过程中,就是需要使用toString和valueOf对数据进行处理。
调用规则
1、如果定义了valueOf,并且valueOf返回一个原始数据类型,大多数情况下优先调用valueOf
let obj={
a:1
}
obj.toString=()=>10
obj.valueOf=()=>100
console.log(1+obj);//101
console.log('hello'+obj);//hello100
console.log(+obj)//100
2、如果不定义valueOf(或者valueOf返回的不是原始数据类型),并且定义了toString(且toString返回一个原始数据类型),调用toString
let obj={
a:1
}
obj.toString=()=>10
// obj.valueOf=()=>100
console.log(1+obj);//11
console.log('hello'+obj);//hello10
console.log(+obj)//10
let obj={
a:1
}
obj.toString=()=>10
obj.valueOf=()=>{return {a:1}}
console.log(1+obj);//11
console.log('hello'+obj);//hello10
console.log(+obj)//10
3、如果将toString和valueOf方法都设置为null,或者都没有返回原始数据类型,报错
let obj={
a:1
}
obj.toString=null
obj.valueOf=null
console.log(1+obj);
console.log('hello'+obj);
console.log(+obj)
表示无法转化为原始数据类型
几种特殊情况
1、Date对象,默认先调用toString方法
let date=new Date();
console.log(date.valueOf())
console.log(1+date);
console.log('1'+date);
如果将date的toString置空
let date=new Date();
date.toString=null;
console.log(date)
console.log(1+date);
console.log('1'+date);
如果将toString方法的返回设置为非原始数据类型,也会调用valueOf
let date=new Date();
date.toString=()=>{return {}};
console.log(date)
console.log(1+date);
console.log('1'+date);
2、String()和Number()的强制转化
String()方法会优先调用toString方法,Number会优先调用valueOf方法
let obj={
a:1
};
obj.toString=()=>{return 5}
obj.valueOf=()=>{return 3}
console.log(String(obj))//5
console.log(Number(obj))//3
注意:如果Number中的进过valueOf转化得到的值不是number类型,会输出NaN
3、alert和join
使用alert输出,会优先调用toString方法
let obj={
a:3
}
obj.toString=()=>{return 4}
obj.valueOf=()=>{return 1}
alert(obj)//4
alert(['obj=',obj].join(''))//obj=4
alert就算没有重定义toString方法,也会调用默认的toString方法;
let obj={
a:1
}
obj.valueOf=()=>3
alert(obj);
可以通过将obj的toString设为null来调用valueOf方法
而数组中如果存在引用数据类型,在调用数组的join方法时,会先调用引用数据的toString方法
总结
1、数据转化的最终结果一定是原始数据类型,也就是valueOf和toString两者必须有一个最后的返回结果是原始数据类型,否则就会出现报错信息;
2、toString优先级比较高的对象(部分特例),先判断toString是否存在,然后toString是否返回原始数据类型,如果不是改为去判断valueOf
3、valueOf优先级高的对象(大部分情况),先从valueOf开始判断,然后再去判断toString;
欢迎评论,有什么不足欢迎指出,不胜感激!