当前位置:  开发笔记 > 编程语言 > 正文

Javascript中的valueOf()与toString()

如何解决《Javascript中的valueOf()与toString()》经验,为你挑选了2个好方法。

在Javascript中,每个对象都有一个valueOf()和toString()方法.我原以为每当调用字符串转换时都会调用toString()方法,但显然它被valueOf()所取代.

例如,代码

var x = {toString: function() {return "foo"; },
         valueOf: function() {return 42; }};
window.console.log ("x="+x);
window.console.log ("x="+x.toString());

将打印

x=42
x=foo

这让我觉得倒退..如果x是一个复数,例如,我希望valueOf()给我它的大小,但每当我想转换成一个字符串我就会想要像"a + bi"这样的东西.而且我不想在隐含字符串的上下文中显式调用toString().

这只是它的方式吗?



1> user187291..:

("x ="+ x)给出"x =值"而不是"x = tostring"的原因如下.在评估"+"时,javascript首先收集操作数的原始值,然后根据每个基元的类型决定是否应该应用加法或连接.

所以,这就是你认为它的工作方式

a + b:
    pa = ToPrimitive(a)
    if(pa is string)
       return concat(pa, ToString(b))
    else
       return add(pa, ToNumber(b))

这就是实际发生的事情

a + b:
    pa = ToPrimitive(a)
    pb = ToPrimitive(b)*
    if(pa is string || pb is string)
       return concat(ToString(pa), ToString(pb))
    else
       return add(ToNumber(pa), ToNumber(pb))

也就是说,toString应用于valueOf的结果,而不是原始对象.

有关进一步参考,请参阅ECMAScript语言规范中的第11.6.1节"加法运算符"(+).


*在字符串上下文调用时,ToPrimitive 调用toString,但这不是这种情况,因为'+'不强制执行任何类型上下文.


不应该在"实际"块中的条件读取"if(pa是string && pb是string)"吗?即"&&"而不是"||" ?
标准肯定说"或"(见链接).

2> bcherry..:

在我得到答案之前,这里有一些细节:

var x = {
    toString: function () { return "foo"; },
    valueOf: function () { return 42; }
};

alert(x); // foo
"x=" + x; // "x=42"
x + "=x"; // "42=x"
x + "1"; // 421
x + 1; // 43
["x=", x].join(""); // "x=foo"

一般而言,该toString功能并非 "胜过" valueOf.ECMAScript标准实际上很好地回答了这个问题.每个对象都有一个[[DefaultValue]]属性,可以按需计算.当要求这个属性时,解释器还提供了一个"提示",表示它期望的值.如果提示是String,则toString之前使用valueOf.但是,如果提示是Number,那么valueOf将首先使用.请注意,如果只有一个存在,或者它返回非基元,它通常会将另一个作为第二选择.

+运营商一直提供的提示Number,即使第一个操作数是一个字符串值.即使它要求x它的Number表示,因为第一个操作数从中返回一个字符串[[DefaultValue]],它会进行字符串连接.

如果要保证toString调用字符串连接,请使用数组和.join("")方法.

(但是,ActionScript 3.0稍微修改了它的行为+.如果任一操作数是a String,它会将其视为字符串连接运算符并String在调用时使用提示[[DefaultValue]].因此,在AS3中,此示例产生"foo,x = foo,foo" = x,foo1,43,x = foo".)


对于内置的Date类,情况似乎并非如此.`(""+ new Date(0))=== new Date(0).toString()`.当一个Date对象添加到某个东西时,它似乎总是返回它的`toString()`值.
+1和Thx!我发现[你的博客文章中详细说明了这个答案](http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html)并想在这里链接/分享.这个答案真的很有帮助(包括Dmitry A. Soshnikov的评论).
实际上,'+'不使用提示(参见$ 11.6.1)因此ToPrimitive调用`[[DefaultValue]](no-hint)`,这相当于`[[DefaultValue]](number)`.
推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有