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它要求x
的Number
表示,因为第一个操作数从[[DefaultValue]]
返回一个string,所以它会进行string连接。
如果要确保toString
被调用string连接,请使用数组和.join("")
方法。
(ActionScript 3.0略微修改了+
的行为,但是,如果任一操作数是一个String
,它将把它当作string连接操作符,并在调用[[DefaultValue]]
时使用提示String
,所以在AS3中, “foo,x = foo,foo = x,foo1,43,x = foo”。)