toString和valueOf

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

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

猜你喜欢

转载自blog.csdn.net/weixin_43801564/article/details/85708488