参考加引用这位大佬:juejin.cn/post/687321…
1、两个方法存在的意义
- 基本上,所有JS数据类型都拥有这两个方法,
null除外
。它们俩是位于原型链上的方法,也是为了解决javascript值运算与显示的问题
valueOf
和 toString
几乎都是在出现操作符(+-*/==><)
时被调用(隐式转换)
2、toString
返回一个表示该对象的字符串,当对象表示为文本值或以期望的字符串方式被引用时,toString方法被自动调用
(1)各种数据类型手动调用显示
注意:对象调用时,变成
[object Object]
。数组调用时,就变成数组内容以逗号连接的字符串,相当于Array.join(',')
let a = {}
let b = [1, 2, 3]
let c = '123'
let d = function(){ console.log('fn') }
console.log(a.toString()) // '[object Object]' --- 注意
console.log(b.toString()) // '1,2,3' --- 注意
console.log(c.toString()) // '123'
console.log(d.toString()) // 'function(){ console.log('fn') }'
(2)精准数据类型判断
这里就不做讲解,详细可以看这篇文章:js判断数据类型的六种方式总结
(3)什么情况下自动调用
使用操作符的时候,如果其中一边为对象,则会先调用toSting
方法,也就是隐式转换
,然后再进行操作。
let c = [1, 2, 3]
let d = {a:2}
Object.prototype.toString = function(){
console.log('Object')
}
Array.prototype.toString = function(){
console.log('Array')
return this.join(',') // 返回toString的默认值(下面测试)
}
console.log(2 + 1) // 3
console.log('s') // 's'
console.log('s'+2) // 's2'
console.log(c < 2) // false (一次 => 'Array')
console.log(c + c) // "1,2,31,2,3" (两次 => 'Array')
console.log(d > d) // false (两次 => 'Object')
(4)重写toString
class A {
constructor(count) {
this.count = count
}
toString() {
return '我有这么多钱:' + this.count
}
}
let a = new A(100)
console.log(a) // A{count: 100}
console.log(a.toString()) // 我有这么多钱:100
console.log(a + 1) // 我有这么多钱:1001
3、vauleOf
返回当前对象的原始值
同样具有以上的自动调用和重写方法,其它方面有所区别
let c = [1, 2, 3]
let d = {a:2}
console.log(c.valueOf()) // [1, 2, 3]
console.log(d.valueOf()) // {a:2}
4、两者区别
- 二者并存的情况下,在数值运算中(运算符),优先调用了
valueOf
,字符串运算中,优先调用了toString
。
class A {
valueOf() {
return 2
}
toString() {
return '哈哈哈'
}
}
let a = new A()
console.log(String(a)) // '哈哈哈' => (toString)
console.log(Number(a)) // 2 => (valueOf)
console.log(a + '22') // '222' => (valueOf)
console.log(a == 2) // true => (valueOf)
console.log(a === 2) // false => (严格等于不会触发隐式转换)
进一步证明
- 先去掉valueOf
class A {
toString() {
return '哈哈哈'
}
}
let a = new A()
console.log(String(a)) // '哈哈哈' => (toString)
console.log(Number(a)) // NaN => (toString)
console.log(a + '22') // '哈哈哈22' => (toString)
console.log(a == 2) // false => (toString)
- 再去掉toString
class A {
valueOf() {
return 2
}
}
let a = new A()
console.log(String(a)) // '[object Object]' => (toString)
console.log(Number(a)) // 2 => (valueOf)
console.log(a + '22') // '222' => (valueOf)
console.log(a == 2) // true => (valueOf)