代码之家  ›  专栏  ›  技术社区  ›  brainjam

javascript中的valueof()与toString()。

  •  106
  • brainjam  · 技术社区  · 16 年前

    在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()。

    就是这样吗?

    2 回复  |  直到 9 年前
        1
  •  100
  •   hzpz    10 年前

    为什么(“x=”+x)给出“x=value”而不是“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的结果,而不是应用于原始对象。

    如需进一步参考,请参阅第11.6.1节。 The Addition operator ( + ) 在ECMAScript语言规范中。


    *在字符串上下文中调用时,toprimitive 调用ToString,但这里不是这样,因为“+”不强制任何类型上下文。

        2
  •  70
  •   bcherry    13 年前

    在我找到答案之前,这里有一点更详细的内容:

    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 ,然后 弦线 以前使用 价值 . 但是,如果提示是 Number ,然后 价值 将首先使用。注意,如果只有一个存在,或者它返回一个非原语,那么它通常会调用另一个作为第二个选项。

    这个 + 操作员始终提供提示 ,即使第一个操作数是字符串值。即使它要求 x 为其 表示法,因为第一个操作数返回 [[默认值]] ,它执行字符串连接。

    如果你想保证 弦线 对于字符串连接调用,请使用数组和 .join("") 方法。

    (actionscript 3.0稍微修改了 + 然而。如果任一操作数是 ,它将把它视为字符串串联运算符并使用提示 当它呼唤 [[默认值]] . 因此,在AS3中,这个示例生成“foo,x=foo,foo=x,foo1,43,x=foo”。)