valueOf和toString两个函数 是number、string、boolean、object、symbol原型链上共有的函数(null和undefined两种数据类型没有)
这两个函数主要是用来干什么的呢?
答案是:值运算和显示问题,一般在隐式类型转换时会自动调用。
- 对number、string、boolean、object、symbol数据类型调用valueOf方法,得到的都是数据本身。
(null、undefined两种类型的原型上没有valueOf方法)
var a = 1;
var aa = a.valueOf();
console.log(aa == a); //true
var b = 'a';
var bb = b.valueOf();
console.log(bb === b); //true
var c = true;
var cc = c.valueOf();
console.log(cc === c); //true
var obj = {
name: 'age'
};
var objobj = obj.valueOf();
console.log(obj === objobj); //true
var s = Symbol();
var ss = s.valueOf();
console.log(ss === s); //true
- 对number、string、boolean、symbol类型数据调用toString方法得到的是对应的字符串;
对object类型数据调用toString的方法得到的是"[object Object]"。(null和undefined两种数据类型的原型链上没有toString方法)
var a = 1;
var aaa = a.toString(); // "1"
var b = 'a';
var bbb = b.toString(); // "a"
var c = true;
var ccc = c.toString(); // "true"
var obj = {
name: 'age',
};
var objobjobj = obj.toString(); //"[object Object]"
var s = Symbol();
var sss = s.toString(); //"Symbol()"
重写valueOf和toString
- 只重写valueOf
var a = {
i: 10,
valueOf: function() {
console.log('valueOf')
return this.i + 30;
}
}
console.log(a > 20); // valueOf true
alert(a); // [object Object]
console.log(a == 20) //value false
console.log(String(a)) // [object Object]
console.log('' + a); // valueOf 40
console.log(++a); // valueOf 41
console.log(-a); // valueOf -41
//如果把++a运算放在前面,a就变成number类型,
//a.toString就不是[object Object],而是数字
结论:只重写了valueOf方法的话,涉及到值运算优先调用valueOf方法,涉及到显示问题还是优先调用原型链上的toString方法。
- 只重写toString
var aaa = {
i: 10,
toString: function() {
console.log('toString')
return this.i + 10;
}
}
alert(aaa); // toString 20
console.log('' + aaa); // toString 20
console.log(String(aaa)) // toString 20
console.log(aaa == 20) //toString true
console.log(aaa > 20); // toString false
console.log(-aaa); // toString -20
console.log(++aaa); // toString 21
//如果把++aaa运算放在前面,a就变成number类型
结论:只重写了toString方法的话,toString方法比原型链上的valueOf方法优先级高。
- 重写valueOf和toString
var aaa = {
i: 10,
valueOf: function() {
console.log('valueOf')
return this.i + 30;
},
toString: function() {
console.log('toString')
return this.i + 10;
}
}
alert(aaa); // toString 20
console.log(String(aaa)) // toString 20
console.log('' + aaa); // valueOf 40
console.log(aaa > 20); // valueOf true
console.log(aaa == 40) //valueOf true
console.log(+aaa); // valueOf 40
console.log(++aaa); // valueOf 41
//如果把++aaa运算放在前面,a就变成number类型
结论:及到操作符的问题,valueOf的优先级比toString的优先级高,涉及到显示问题,toString方法优先级比valueOf方法高。
经典前端面试题:
如何能够使得下列的表达式返回true
a == 1 && a == 2 && a == 3;
解法:
var a = {
i: 0,
valueOf: function() {
console.log('valueOf')
return ++this.i;
},
}
console.log(a == 1 && a == 2 && a == 3); //true
总结:重写了valueOf方法的话,涉及到值运算优先调用valueOf方法,涉及到显示问题还是优先调用原型链上的toString方法。(重写toString也能起到同样效果)