前言:前面我们过了类型的转换,但都只是关于原始类型之间的相互转换。并没有说到对象的类型转换,这篇文章我们来了解下对象是如何进行类型转换地 。
1.JavaScript各个对象中valueOf与toString来源
JavaScript中一切皆对象,只要你了解过原型链就会知道任何一个对象的原始链的顶层指向Object.prototype,而Object中就存在valueOf和toString 方法,对于一切继承Object的对象,就将会继承了Object中的方法。对于继承的valueOf与toString 都可以被重写,而JavaScript 对于不同对象之间的valueOf与toString也可能不同。
2.valueOf 与 toString 转换规则
valueOf: 返回指定对象的原始值。
如下为给对象调用valueOf返回值的情况
例:
// Number
let num = new Number(10);
console.log(typeof num); // object
console.log(num.valueOf()); // 10
// String
let str = new String("hello");
console.log(typeof str) // object
console.log(str.valueOf()) // "hello"
// Boolean
let bool = new Boolean()
console.log(typeof bool) // object
console.log(bool.valueOf()) // false
// Array
let arr = [1,2,5]
console.log(typeof arr) // object
console.log(arr.valueOf()) // [1,2,5]
// Object
let user = {
name: "Jason",
age: 24
}
console.log(typeof user) // object
console.log(user.valueOf()) // {name: "Jason",age: 24}
//Date
let now = new Date()
console.log(typeof now) // object
console.log(now.valueOf()) // 1600001038411
// Function
function fun(){
return 10;
}
console.log(typeof fun) // function
console.log(fun.valueOf()) // fun(){return 10;}
toString: 返回表示该对象的字符串。
如下为给对象调用toString返回值的情况
例:
// Number
let num = new Number(10);
console.log(typeof num); // object
console.log(num.toString()); // '10'
// String
let str = new String("hello");
console.log(typeof str) // object
console.log(str.toString()) // "hello"
// Boolean
let bool = new Boolean()
console.log(typeof bool) // object
console.log(bool.toString()) // 'false'
// Array
let arr = [1,2,5]
console.log(typeof arr) // object
console.log(arr.toString()) // '1,2,5'
// Object
let user = {
name: "Jason",
age: 24
}
console.log(typeof user) // object
console.log(user.toString()) //"[object, Object]"
//Date
let now = new Date()
console.log(typeof now) // object
console.log(now.toString()) //"Sun Sep 13 2020 20:43:58 GMT+0800 (中国标准时间)"
// Function
function fun(){
return 10;
}
console.log(typeof fun) // function
console.log(fun.toString()) // 'fun(){return 10;}'
注:function 函数隶属于Object, 更本不存在function类型,JavaScript只是为了编程方便而对函数区分对待。
3.valueOf与toString类型转换如何调用。
所有的对象在布尔上下文(context)中均为 true
。所以对象不存在 to-boolean 转换,只有向字符串和数字的转换,对于对象来说不管是强行转换还是自动转换,JavaScript 会隐式调用valueOf和toString方法。
4.valueof与toString 的优先级
1.在不重写方法的情况下
- to-Number转换为Number 类型时调用 valueOf 方法
- to-String 转换为String 类型时调用 toString 方法
2.在toString 方法重写的情况下
- to-Number转换为Number 类型时调用 toString 方法
- to-String 转换为String 类型时调用 toString 方法
3.两个方法都重写的情况下
- to-Number转换为Number 类型时调用 valueOf 方法
- to-String 转换为String 类型时调用 toString 方法
4.在valueOf方法重写的情况下
- to-Number转换为Number 类型时调用 valueOf 方法
- to-String 转换为String 类型时调用 toString 方法
总结: 只要是toString方法不重写 在to-Number时调用valueOf,to-String调用toString,反之将优先会调用toString方法。
例:
let num = new Number(10);
// to-number
console.log(Number(num)) // 10
console.log(+num) // 10
// to-string
console.log(String(num)) // "10"
分析: valueOf返回的是原始值,toString返回的是对象的字符串
1.to-number 时调用valueOf 返回 10
2.to-string 时调用toString 返回 '10'
5.alert函数
在JavaScrpit中经常会用到alert 函数,该函数在执行是会去调用toString函数将函数中要显示的值或者对象进行转换。转换根据toString函数转换规则。
alert({}) // "[object Object]"
alert(1) // "1"
alert([2,4,6]) // "2,4,6"
6.Symbol.toPrimitive
Symbol.toPrimitive是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,如果对象中存在个属性时,当一个对象转换为对应的原始值时,会优先调用此函数。
let user = {
name: 'Jason',
age: 24,
[symbol.toPrimitive](hint){
if(hint === 'string') return this.name;
eles if(hint === 'number') return this.age;
}
}
//测试
console.log(String(user)) // hint: string 打印 "Jason"
console.log(Number(user)) // hint: numbber 打印 24
分析: 对于Symbol.toPrimitive被调用时,将会传如转换的类型,我们可以针对转换的类型自定义我们想让它转换成的类型或值。hint 为指定转换的类型名。
注: Symbol.toPrimitive存在时优先调用,不存在时才去调用valueOf与toString方法。