toString和valueOf

本文深入解析JavaScript中toString和valueOf方法的使用及调用规则,解释不同数据类型如何在运算中被处理,包括Date对象的特殊行为,以及String()和Number()的强制类型转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在每个对象中,都会继承两个方法: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对象,就返回了1970.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;

欢迎评论,有什么不足欢迎指出,不胜感激!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值