Nice.
valueOf
返回当前对象的原始值 。具体功能与
toString
大同小异 , 同样具有以上的自动调用和重写方法 。这里就没什么好说的了 , 主要为两者间的区别 , 有请继续往下看????
let c = [1, 2, 3]let d = {a:2}console.log(c.valueOf())// [1, 2, 3]console.log(d.valueOf())// {a:2}复制代码
两者区别- 共同点:在输出对象时会自动调用 。
- 不同点:默认返回值不同 , 且存在优先级关系 。
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=> (严格等于不会触发隐式转换)复制代码
结果给人的感觉是 , 如果转换为字符串时调用toString
方法 , 如果是转换为数值时则调用valueOf
方法 。但其中的
a + '22'
很不和谐 , 字符串合拼应该是调用toString
方法 。为了追究真相 , 我们需要更严谨的实验 。- 暂且先把
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)复制代码
发现有点不同吧?!它没有像上面 toString
那样统一规整 。对于那个 [object Object]
, 我估计是从 Object
那里继承过来的 , 我们再去掉它看看 。class A {valueOf() {return 2}}let a = new A()Object.prototype.toString = null; console.log(String(a))// 2=> (valueOf)console.log(Number(a))// 2=> (valueOf)console.log(a + '22')// '222'=> (valueOf)console.log(a == 2)// true=> (valueOf)复制代码
总结:valueOf
偏向于运算 , toString
偏向于显示 。- 在进行对象转换时 , 将优先调用
toString
方法 , 如若没有重写toString
, 将调用valueOf
方法;如果两个方法都没有重写 , 则按Object
的toString
输出 。 - 在进行强转字符串类型时 , 将优先调用
toString
方法 , 强转为数字时优先调用valueOf
。 - 使用运算操作符的情况下 ,
valueOf
的优先级高于toString
。
MDN:Symbol.toPrimitive 是一个内置的 Symbol 值 , 它是作为对象的函数值属性存在的 , 当一个对象转换为对应的原始值时 , 会调用此函数 。是不是有点懵??? 把它当做一个函数就行了~~