valueOf与toString
valueOf
和toString
是Object.prototype
上的方法,在Js
几乎所有的对象都会继承自Object
,同样由于包装对象的原因,几乎所有的数据类型都能够调用这两个方法,无法调用的有例如null
、undefined
以及Object.create(null)
创建的对象等,通常我们一般不会主动调用这两个方法,而在代码执行的过程中这两个方法会经常被偷偷的调用,而且在不同的情况下会有选择的进行调用。
valueOf
JavaScript
通过调用valueOf
方法将对象转换为原始值,我们很少需要自己调用valueOf
方法,当遇到要预期的原始值的对象时,JavaScript
会自动调用它。默认情况下,valueOf
方法由Object
后面的每个对象继承。每个内置的核心对象都会覆盖此方法以返回适当的值,如果对象没有原始值,则valueOf
将返回对象本身。
JavaScript
的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此不同类型对象的valueOf
方法的返回值和返回值类型均可能不同。
对象 |
返回值 |
Array |
返回数组对象本身。 |
Boolean |
布尔值。 |
Date |
存储的时间是从1970 年1 月1 日午夜开始计的毫秒数UTC 。 |
Function |
函数本身。 |
Number |
数字值。 |
Object |
默认情况下返回对象本身。 |
String |
字符串值。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| var arr = []; console.log(arr.valueOf() === arr);
var date = new Date(); console.log(date.valueOf());
var num = 1; console.log(num.valueOf());
var bool = true; console.log(bool.valueOf() === bool);
var newBool = new Boolean(true); console.log(newBool.valueOf() === newBool);
function funct(){} console.log(funct.valueOf() === funct);
var obj = {}; console.log(obj.valueOf() === obj);
var str = ""; console.log(str.valueOf() === str);
var newStr = new String(""); console.log(newStr.valueOf() === newStr);
|
前文提到过在JavaScript
运行的过程中valueOf
方法经常会被偷偷的调用,我们可以自行重写valueOf
方法,在def.js
中甚至相当灵活使用valueOf
等方式实现了Ruby
风格的类定义工厂,以Child << Parent
的风格实现了继承。
1 2 3 4 5 6 7 8 9 10 11
| class ValueOfTest{ constructor(val){ this.val = val; } valueOf(){ return this.val; } }
var v = new ValueOfTest(10); console.log(v + 1);
|
toString
JavaScript
通过调用toString
方法返回一个表示该对象的字符串,每个对象都有一个toString
方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()
方法被每个Object
对象继承,如果此方法在自定义对象中未被覆盖,toString
返回[object type]
,其中type
是对象的类型。
JavaScript
的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此不同类型对象的toString
方法的返回值和返回值类型均可能不同。
对象 |
返回值 |
Array |
以逗号分割的字符串,如[1,2] 的toString 返回值为1,2 。 |
Boolean |
布尔值的字符串形式。 |
Date |
可读的时间字符串,例如Tue Oct 27 2020 16:08:48 GMT+0800 (中国标准时间) |
Function |
声明函数的Js 源代码字符串。 |
Number |
数字值的字符串形式。 |
Object |
[object Object] 字符串。 |
String |
字符串。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| var arr = [1, 2, 3]; console.log(arr.toString());
var date = new Date(); console.log(date.toString());
var num = 1; console.log(num.toString());
var bool = true; console.log(bool.toString());
function funct(){ var a = 1; } console.log(funct.toString());
var obj = {a: 1}; console.log(obj.toString());
var str = "1"; console.log(str.toString());
|
对比
JavaScript
在不同情况下,会调用不同的方法去处理值,通常来说是会优先调用toString()
方法,而有运算操作符的情况下valueOf()
的优先级高于toString()
,当调用valueOf()
方法无法运算后还是会再调用toString()
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var v = { val: 10, valueOf: function(){ console.log("valueOf"); return this.val; }, toString: function(){ console.log("toString"); return this.val; } }
var obj = {"10": 1};
console.log(v); console.log(1+v); console.log(obj[v]); console.log("" + v); console.log(String(v)); console.log(Number(v)); console.log(v == 10);
|
参考
1 2 3 4 5 6 7
| https://github.com/tobytailor/def.js https://juejin.im/post/6844903812117839879 https://juejin.im/post/6844903967097356302 https://cloud.tencent.com/developer/article/1495536 https://www.cnblogs.com/rubylouvre/archive/2010/10/01/1839748.html https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
|