String(value)とvalue.toString()の違いは何ですか


104

Javascriptには型と型変換に関する多くの「トリック」があるので、これらの2つのメソッドが同じであるか、それともそれらを異なるものにするコーナーケースがあるのか​​と思いますか?

回答:


121

それらは完全に同じではなく、実際には、関数として呼び出されたStringコンストラクター(最初の例)は、最後に、toString渡されたオブジェクトのメソッドを呼び出します。次に例を示します。

var o = { toString: function () { return "foo"; } };
String(o); // "foo"

一方、識別子がnullまたはを参照している場合undefinedtoStringメソッドを使用できません。TypeError例外が発生します

var value = null;
String(null);     // "null"
value.toString(); // TypeError

String関数として呼び出すコンストラクタは、ほぼ同等のようになります。

value + '';

型変換ルールオブジェクト -to- プリミティブが詳述されている、本明細書に記載の[[DefaultValue]]内部動作を。

簡単にまとめると、Object -to- Stringから変換する場合、次の手順が実行されます。

  1. 可能な場合は、toStringメソッドを実行します。
    • resultプリミティブの場合はを返しresult、そうでない場合はステップ2に進みます。
  2. 可能な場合は、valueOfメソッドを実行します。
    • resultプリミティブの場合は戻りresult、そうでない場合はステップ3に進みます。
  3. 投げますTypeError

上記のルールがあれば、関連するセマンティクスの例を作成できます。

var o = {
  toString: function () { return "foo"; },
  valueOf:  function () { return "bar"; }
};

String(o); // "foo"

// Make the toString method unavailable:
o.toString = null;

String(o); // "bar"

// Also make the valueOf method unavailable:
o.valueOf = null;

try { 
  String(o); 
} catch (e) {
  alert(e); // TypeError
}

このメカニズムについて詳しく知りたい場合は、ToPrimitiveToString内部の操作を確認することをお勧めします。

私もこの記事を読むことをお勧めします:


1
3番目の「ウェイ」があります。これを呼び出すとnew String(value)、任意の値で、常に文字列オブジェクトが返されます。
Herbertusz 2016

@Herbertusz new String({toString: null})はをスローしTypeErrorます。
КонстантинВан

シンボルが追加されたことでString()+ ''今ではかなり大きな違いがあります。String(Symbol())実行されますがSymbol() + ''、エラーがスローされます(nullやundefinedとは異なり、Symbol()は誤ったガードを通過するため、x && (x + '')スローできるようになります)。
はい、

24

value.toString()valueがnullの場合、エラーが発生します。String(value)いけない。

例えば:

var value = null;
alert(value.toString());

失敗するでしょうvalue == null

var value = null;
alert(String(value));

「null」(または類似)を示すメッセージを表示する必要がありますが、クラッシュしません。


3
JavaScriptでnullポインターの例外を見たことがありません...どこで見ましたか?
Dagg Nabbit、

いいね。例を挙げればもっと良いでしょう
mykhal

@いいえ、@ casablanca修正済み。私はJavaに慣れています。@mykhalどうですか?
ジョナサン

文字列「null」を返します:)
moefinley '12年

1

String(value)またはなどのvalue.toString()プロパティのない値を除き、すべての場合と同じ結果になります。同じ結果になります。nullundefined''+value


1

String() [ コンストラクタ呼び出し ]は基本的に.toString()を呼び出しています

.toString()String()は、プリミティブ値(数値、ブール値、文字列)で呼び出すことができ、基本的に特別なことは何もしません。

true => 'true'

false => 'false'

17 => '17'

'こんにちは' => 'こんにちは'

しかし、オブジェクトでこれらの関数を呼び出すと、興味深いことが起こります。

オブジェクトに独自の.toString()関数がある場合、このオブジェクトを文字列として処理する必要があるときに呼び出されます(明示的/暗黙的)

let obj = {
           myName:"some object",
           toString:function(){ return this.myName; } 
          }

//implicitly treating this obj as a string
"hello " + obj; //"hello some object"

//OR (explicitly)
"hello " + String(obj) //calling the existent toString function

//OR
"hello " + obj.toString(); //calling toString directly

ちなみに、このオブジェクトを数値として扱いたい場合は、.valueOf()関数が定義されている必要があります。

1つのオブジェクトに両方がある場合はどうなりますか?

このオブジェクトを文字列として扱いたい場合=> .toString()を使用

このオブジェクトを数値として扱いたい場合=> use .valueOf()

.valueOf()のみが定義されている場合はどうなりますか?

オブジェクト内で定義された.valueOf()は、オブジェクトを文字列として処理する場合でも、数値として処理する場合でも呼び出されます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.