基本上,所有JS数据类型都拥有这两个方法,null除外。它们俩是位于原型链上的方法,也是为了解决javascript值运算与显示的问题。

valueOftoString 几乎都是在出现操作符(+-*/==><)时被调用(隐式转换)。

比如 字符串 + 数字 ,数字会被自动转为字符串

  1. '3' + 3 //'33'


toString

返回一个表示该对象的字符串,当对象表示为文本值或以期望的字符串方式被引用时,toString方法被自动调用。

1. 手动调用看看什么效果

嗯,跟介绍的一样,没骗人,全部都转成了字符串。

比较特殊的地方就是,

表示对象的时候,变成[object Object]

表示数组的时候,就变成数组内容以逗号连接的字符串,相当于Array.join(',')

  1. let a = {}
  2. let b = [1, 2, 3]
  3. let c = '123'
  4. let d = function(){ console.log('fn') }
  5. console.log(a.toString()) // '[object Object]'
  6. console.log(b.toString()) // '1,2,3'
  7. console.log(c.toString()) // '123'
  8. console.log(d.toString()) // 'function(){ console.log('fn') }'

2. 最精准的类型判断

这种属于更精确的判断方式,在某种场合会比使用 typeof & instanceof 来的更高效和准确些。

  1. toString.call(()=>{}) // [object Function]
  2. toString.call({}) // [object Object]
  3. toString.call([]) // [object Array]
  4. toString.call('') // [object String]
  5. toString.call(22) // [object Number]
  6. toString.call(undefined) // [object undefined]
  7. toString.call(null) // [object null]
  8. toString.call(new Date) // [object Date]
  9. toString.call(Math) // [object Math]
  10. toString.call(window) // [object Window]

3. 什么时候会自动调用呢

使用操作符的时候,如果其中一边为对象,则会先调用toSting方法,也就是隐式转换,然后再进行操作。

  1. let c = [1, 2, 3]
  2. let d = {a:2}
  3. Object.prototype.toString = function(){
  4. console.log('Object')
  5. }
  6. Array.prototype.toString = function(){
  7. console.log('Array')
  8. return this.join(',') // 返回toString的默认值(下面测试)
  9. }
  10. Number.prototype.toString = function(){
  11. console.log('Number')
  12. }
  13. String.prototype.toString = function(){
  14. console.log('String')
  15. }
  16. console.log(2 + 1) // 3
  17. console.log('s') // 's'
  18. console.log('s'+2) // 's2'
  19. console.log(c < 2) // false (一次 => 'Array')
  20. console.log(c + c) // "1,2,31,2,3" (两次 => 'Array')
  21. console.log(d > d) // false (两次 => 'Object')

valueOf

返回当前对象的原始值。

具体功能与toString大同小异,同样具有以上的自动调用和重写方法。

这里就没什么好说的了,主要为两者间的区别

  1. let c = [1, 2, 3]
  2. let d = {a:2}
  3. console.log(c.valueOf()) // [1, 2, 3]
  4. console.log(d.valueOf()) // {a:2}

两者区别

  • 共同点:在输出对象时会自动调用。
  • 不同点:默认返回值不同,且存在优先级关系

二者并存的情况下,

数值运算中,优先调用了valueOf字符串运算中,

优先调用了toString

  1. class A {
  2. valueOf() {
  3. return 2
  4. }
  5. toString() {
  6. return '哈哈哈'
  7. }
  8. }
  9. let a = new A()
  10. console.log(String(a)) // '哈哈哈' => (toString)
  11. console.log(Number(a)) // 2 => (valueOf)
  12. console.log(a + '22') // '222' => (valueOf)
  13. console.log(a == 2) // true => (valueOf)
  14. console.log(a === 2) // false => (严格等于不会触发隐式转换)

结果给人的感觉是,如果转换为字符串时调用toString方法,如果是转换为数值时则调用valueOf方法。
但其中的 a + '22' 很不和谐,字符串合拼应该是调用toString方法。为了追究真相,我们需要更严谨的实验。

暂且先把 valueOf 方法去掉

  1. class A {
  2. toString() {
  3. return '哈哈哈'
  4. }
  5. }
  6. let a = new A()
  7. console.log(String(a)) // '哈哈哈' => (toString)
  8. console.log(Number(a)) // NaN => (toString)
  9. console.log(a + '22') // '哈哈哈22' => (toString)
  10. console.log(a == 2) // false => (toString)

去掉 toString 方法看看

  1. class A {
  2. valueOf() {
  3. return 2
  4. }
  5. }
  6. let a = new A()
  7. console.log(String(a)) // '[object Object]' => (toString)
  8. console.log(Number(a)) // 2 => (valueOf)
  9. console.log(a + '22') // '222' => (valueOf)
  10. console.log(a == 2) // true => (valueOf)

总结:

valueOf偏向于运算,toString偏向于显示。

  1. 在进行对象转换时,将优先调用toString方法,如若没有重写 toString,将调用 valueOf 方法;如果两个方法都没有重写,则按ObjecttoString输出。

  2. 在进行强转字符串类型时,将优先调用 toString 方法,强转为数字时优先调用 valueOf

  3. 使用运算操作符的情况下,valueOf的优先级高于toString

    参考

https://mp.weixin.qq.com/s?__biz=Mzg2NDAzMjE5NQ==&mid=2247486548&idx=1&sn=bd17050ee15d6cfc1637183c01930196&chksm=ce6ec8f8f91941ee234e1316d51ec4c401dc0a14559ffb9830bda8022086f42446158113548c&mpshare=1&scene=24&srcid=0922TtYDnkggZ6WSm8u3ZtHP&sharer_sharetime=1600735678555&sharer_shareid=b6060ac630e54fc1802d87bb288ed55b&key=dbdefc5d690db195199f81b505be9580286085ef4eff677431fda4009a0ea8473fbbd859fa992e87fa175547dd8b89b6c055ff53330f0def597b32790730214cfcd6b1f2010401a95ec0379efe36b10fc8096ffc93d3b62891faed847523b24e27a35bf9b21ee4cd56e3e556a2ee7044224a75208304260f44637e17a8137e33&ascene=14&uin=MTEyNDAxNTA4Mw%3D%3D&devicetype=Windows+10+x64&version=62090538&lang=zh_CN&exportkey=AxpUA36iAkS0BsKM%2FOwaEGA%3D&pass_ticket=oi7DDN3ZEp0eXsv7sSPw8%2FcTknq3bzmow0evY48WToJKgNwbinXWc8gaNmq1NfKI&wx_header=0