JavaScript的toString()和valueOf()区别到底是什么,tostringvalueof
JavaScript的toString()和valueOf()区别到底是什么,tostringvalueof
从《JavaScript高级程序设计》这本书里面
[javascript] view plain copy
- var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
- alert(colors.toString()); // red,blue,green
- alert(colors.valueOf()); // red,blue,green
- alert(colors); // red,blue,green
的这个例子,我们会有一个非常大的疑问
toString()和valueOf()区别到底是什么?
那么不如看下一个我写的例子
[javascript] view plain copy
- var arr = [1,2,3];
- alert(Array.isArray(arr.valueOf()));
- alert(Array.isArray(arr.toString()));
结果是第一个是true而第二个是false
为什么呢,其实valueOf()调用完以后还是返回一个数组
这个数组被alert的时候会调用toString()函数
所以不是valueOf()和toString()函数相同,而是,根本就是间接的调用了toString()函数!
什么?你不信?
那好吧,我们来测试一下
[javascript] view plain copy
- var arr = [1,2,3];
- arr.toString = function () {
- alert("你调用了toString函数");
- }
- alert(arr.valueOf());
(坑爹阿csdn,朕的代码缩进)
来来,猜猜结果。
结果就是我们会看到“你调用了toString函数”。
而对于数值,我们可以调用valueOf的时候直接可以获得数字进行计算,不必转化成字符串,所以不会调用toString
反言之,如果我们需要获得操作对象的字符串形式的时候就会调用其toString函数
举个例子
以下代码来自脚本之家的相关文章
[javascript] view plain copy
- var bbb = {
- i: 10,
- toString: function() {
- console.log('toString');
- return this.i;
- },
- valueOf: function() {
- console.log('valueOf');
- return this.i;
- }
- }
- alert(bbb);// 10 toString
- alert(+bbb); // 10 valueOf
- alert(''+bbb); // 10 valueOf
- alert(String(bbb)); // 10 toString
- alert(Number(bbb)); // 10 valueOf
- alert(bbb == '10'); // true valueOf
- alert(bbb === '10'); // false
他的文章讲的不是很清楚,为什么在我们重写了代码以后就会出现这样的情况
在这里我说一下我的理解
valueOf的意思是返回最适合该对象类型的原始值,而toString则是将在该对象类型的原始值以字符串形式返回。
第一个
[javascript] view plain copy
- alert(bbb);// 10 toString
第二个
[javascript] view plain copy
- <span style="font-family: Arial, Helvetica, sans-serif;">alert(+bbb); // 10 valueOf</span>
同理,alert要的是字符串不是原始值,其实是+bbb这个东西被调用了toString,而bbb被调用了valueOf
为了验证我们这样写
[javascript] view plain copy
- var a = {
- i: 1,
- valueOf: function () {
- alert("你调用了a的valueOf函数");
- return this.i;
- },
- toString: function () {
- alert("你调用了a的toString函数");
- return this.i;
- }
- };
- var c = {
- i: +a,
- valueOf: function () {
- alert("你调用了c的valueOf函数");
- return this.i;
- },
- toString: function () {
- alert("你调用了c的toString函数");
- return this.i;
- }
- };
- alert(c);
其中让c=+a,那么即可知道结果,果然如此,调用了a的valueOf和c的toString
第三个
[javascript] view plain copy
- alert(''+bbb); // 10 valueOf
第四个
[javascript] view plain copy
- alert(String(bbb)); // 10 toString
第五个
[javascript] view plain copy
- alert(Number(bbb)); // 10 valueOf
呐,代码例子
[javascript] view plain copy
- var c = {
- i: "11111xxxx",
- valueOf: function () {
- alert("你调用了c的valueOf函数");
- return this.i;
- },
- toString: function () {
- alert("你调用了c的toString函数");
- return this.i;
- }
- };
- alert(c);
第六个
[javascript] view plain copy
- alert(bbb == '10'); // true valueOf
第七个也就是最后一个
[javascript] view plain copy
- alert(bbb === '10'); // false
讨论
另外,对于原文的这句话“ 在进行对象转换时(例如:alert(a)),将优先调用toString方法,如若没有重写toString将调用valueOf方法,如果两方法都不没有重写,但按Object的toString输出。”我不是很认同
原文例子
[javascript] view plain copy
- var aa = {
- i: 10,
- toString: function() {
- console.log('toString');
- return this.i;
- }
- }
- alert(aa);// 10 toString
- alert(+aa); // 10 toString
- alert(''+aa); // 10 toString
- alert(String(aa)); // 10 toString
- alert(Number(aa)); // 10 toString
- alert(aa == '10'); // true toString
我的观点有些不同,重写了的toString会被未重写的其prototype的valueOf隐式调用,而不是优先调用toString。虽然结果不同,但是其实没有优先级的变化。(但是我只能证明重写了的toString会被未重写的其prototype的valueOf隐式调用,却不能证明未重写和重写后的优先级变化读者如果完成了验证请教教我,我的js上周一才开始学。以下是例子)
[javascript] view plain copy
- var a = {
- i: 1,
- valueOf: function () {
- alert("你调用了a的valueOf函数");
- return Object.prototype.valueOf();
- },
- toString: function () {
- alert("你调用了a的toString函数");
- return this.i;
- }
- };
- alert(+a);
- alert(''+a);
结果的确调用了a的toString和a的valueOf,而我们可以很轻易的从最初的原文例子看到,这两个alert是没有调用国toString的,那么我们即可证明重写了的toString会被未重写的其prototype的valueOf隐式调用。
另一个原文的例子
[javascript] view plain copy
- var bb = {
- i: 10,
- valueOf: function() {
- console.log('valueOf');
- return this.i;
- }
- }
- alert(bb);// [object Object]
- alert(+bb); // 10 valueOf
- alert(''+bb); // 10 valueOf
- alert(String(bb)); // [object Object]
- alert(Number(bb)); // 10 valueOf
- alert(bb == '10'); // true valueOf
而valueOf被重写以后,这个bb的对象没有toString,自然就会调用其prototype的toString,而那个toString的内容必然是
[javascript] view plain copy
- function toString() {
- return '[object Object]';
- }
,所以其实这个验证并没有什么意义。无论重写哪个函数最终的优先级都没变。
总结
所以那篇的结论并不是最根本的问题,最根本的问题是到底操作对象所处的环境是什么样的。
如果要求的是原始值那么就会调用valueOf,如果要求的是字符串那么就会调用toString。
转自:http://blog.csdn.net/cct418/article/details/50889987
相关文章
- 暂无相关文章
用户点评