# 1. 重写toString和valueOf
看完了上篇的对象转字符串,不知道你对toPrimititve的转换流程掌握了多少呢?
如果你感觉之前的那些例子还不太具有说明性,也就是说你还是没有感觉到JS确实是按我画的那个流程图来进行转换的话,你可以看看这里。
我们在上篇的6.1中提到过了,大部分的对象都是可以通过原型链查找到Object.prototype上的toString或者valueOf方法,然后使用它们。
但是你想想,如果我这个对象本身就有toString或者valueOf方法的话是不是就可以不用Object.prototype上的了,这其实就是我们常听到的重写。
你也许可以用这样的方式来覆盖原型链上的这两个方法:
let obj = {
toString () {
return '1'
},
valueOf () {
return 1
}
}
@前端进阶之旅: 代码已经复制到剪贴板
甚至你还可以直接修改Object.prototype上的方法:
Object.prototype.toString = function () {
return 1
}
var b = {}
console.log(String(b)) // '1'
@前端进阶之旅: 代码已经复制到剪贴板
(当然,这种肯定是不推荐的哈,这会影响所有的对象)
# 1.1 题目一
(通过重写toString()和valueOf()来判断我们之前的toPrimitive流程是否正确)
上面👆两个例子我只是想告诉你,既然我们可以重写对象上的toString()和valueOf,那如果我们在重写的函数里面再加上console.log(xxx),不就可以知道对象转原始值的具体过程是不是按我们设想的方式执行下去了吗?
比如这样:
var b = {
toString () {
console.log('toString')
return 1
},
valueOf () {
console.log('valueOf')
return [1, 2]
},
}
console.log(Number(b))
@前端进阶之旅: 代码已经复制到剪贴板
想一下这里的执行结果 🤔️?
既然是用Number()方法来进行转换的话,那也就是执行了伪代码toPrimitive(obj, 'number')了。
那也就是说会先调用valueOf()函数,然后判断这个函数的返回值是否为原始值,再决定是继续调用toString()还是返回。
- 很显然,由于这里的
valueOf()被重写了,所以调用valueOf()之后返回的是一个引用类型
