详谈js中toString()和valueOf()

他们主要用于数据转换,并且所有对象都继承了这两个方法:

第一个是toString(),它的作用是返回一个反映这个对象的字符串
第二个是valueOf(),它的作用是返回它相应的原始值

什么是原始值:

原始值:不可变更的值,包括undefined、null、布尔值、数字、和字符串。 看下面这张图,列出了一些基本的类型转换。

在这里插入图片描述

==1、toString()==
在这里插入图片描述

很多类定义了更多特定版本的toString()方法。例如,数组类(Array class)的toString()方法将每个数组元素转换为-一个字符串,并在元素之间添加逗号后合并成结果字符串。函数类(Function class) 的toString()方法返回这个函数的实现定义的表示方式。实际上,这里的实现方式是通常是将用户定义的函数转换为JavaScript源代码字符串。日期类(Date class)定义的toString()方法返回了一个可读的日期和时间字符串。RegExp类 定义的toString()方法将RegExp对象转换为表示正则表达式直接量的字符串。

1
2
3
4
console.log([1, 2, 3].toString());             //  1,2,3
console.log((function(x) {f(x);}).toString()); // function(x) {f(x);}
console.log(/\d+/g.toString()); // /\d+/g
console.log(new Date(2020, 1, 1).toString()); // Sat Feb 01 2020 00:00:00 GMT+0800 (中国标准时间)

==2、valueof()==

另一个转换对象的函数是value0f()。这个方法的任务并未详细定义:如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的value0f()方法简单地返回对象本身,而不是返回一个原始值。数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例的value0f()方法只是简单返回对象本身。日期类定义的valueOf()方法返回它的一个内部表示:2020年1月1日以来的毫秒数。

1
2
var t = new Date(2020, 1, 1);
console.log(t.valueOf()); //1580486400000

总的来说javaScript中对象到字符串的转换经过如下的这些步骤:

  1. 如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。需要注意的是,原始值到字符串的转换在表3-2中已经有了详尽的说明。
  2. 如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么JavaScript会调用value0f()方法。如果存在这个方法,则JavaScript调用它。 如果返回值是原始值,JavaScript将这 个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
  3. 否则,JavaScript无法 从toString()或value0f()获得一一个 原始值,因此这时它将抛
    出一个类型错误异常。

从对象到数字的转换过程中,JavaScript做的相同的事情,只是会先使用valueOf()方法:

  1. 如果对象具有value0f()方法,后者返回-一个原始值,则JavaScript将这 个原始值转换为数字( 如果需要的话)并返回这个数字。
  2. 否则,如果对象具有toString()方法,后者返回一个原始值,JavaScript将其转换并返回。
  3. 否则,JavaScript拋 出一个类型错误异常。

这就很好解释了下面的一个问题:为什么空数组会被转换为数字0,为什么具有单个元素的数组同样会转换成一个数字。

对象转换为数字的细节解释了为什么空数组会被转换为数字0以及为什么具有单个元素的数组同样会转换成一个数字。数组继承了默认的value0f()方法,这个方法返回一个对象而不是一一个原始值,因此,数组到数字的转换则调用toString()方法。空数组转换成为空字符串,空字符串转换成为数字0。含有一个元素的数组转换为字符串的结果和这个元素转换字符串的结果一样。如果数组只包含-一个数字元素,这个数字转换为字符串,再转换回数字。

愿你的坚持都有收获!!!