JavaScript中的valueOf()与toString()

在Javascript中,每个对象都有一个valueOf()和toString()方法。 我会想,toString()方法被调用,每当一个string转换被调用,但显然它是由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()给我它的大小,但每当我想要转换为一个string,我会想像“a + bi”的东西。 而且我不想在隐含string的上下文中显式地调用toString()。

这是这样吗?

(“x =”+ x)给出“x = value”而不是“x = tostring”的原因如下。 当评估“+”时,javascript首先收集操作数的原始值,然后根据每个原语的types决定是否应用加法或连接。

所以,这是你认为它的工作原理

 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节“加法”运算符(+) 。


*当在string上下文调用时,ToPrimitive 调用toString,但在这里不是这种情况,因为'+'不强制任何types上下文。

这里有一个更详细的信息,在我find答案之前:

 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 ,则在valueOf之前使用toString 。 但是,如果提示是Number ,那么将首先使用valueOf 。 请注意,如果只有一个存在,或者它返回一个非原始的,通常会调用另一个作为第二个select。

即使第一个操作数是string值, +操作符也总是提供提示Number 。 尽pipe它要求xNumber表示,因为第一个操作数从[[DefaultValue]]返回一个string,所以它会进行string连接。

如果要确保toString被调用string连接,请使用数组和.join("")方法。

(ActionScript 3.0略微修改了+的行为,但是,如果任一操作数是一个String ,它将把它当作string连接操作符,并在调用[[DefaultValue]]时使用提示String ,所以在AS3中, “foo,x = foo,foo = x,foo1,43,x = foo”。)