1. ホーム
  2. javascript

[解決済み] JavascriptにおけるvalueOf()とtoString()の比較

2022-08-22 14:35:43

質問

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() を呼び出す必要はないでしょう。

これは単なる方法なのでしょうか?

どのように解決するのですか?

("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節をチェックしてください。 加算演算子 ( + ) を参照してください。


*文字列コンテキストで呼び出された場合、ToPrimitiveは が行います。 はtoStringを呼び出しますが、'+'は型コンテキストを強制しないため、ここではそのようなことはありません。