Object.prototype.toString()

toString()Object インスタンスのオブジェクトで、このオブジェクトを表す文字列を返します。このメソッドは、独自の型変換ロジックのために派生オブジェクトがオーバーライドするためのものです。

試してみましょう

構文

js
toString()

引数

既定では、 toString() は引数を取りません。ただし、Object を継承するオブジェクトは、パラメーターを取る独自の実装で toString() をオーバーライドできます。例えば、 Number.prototype.toString() および BigInt.prototype.toString() メソッドは、オプションで引数 radix を取ります。

返値

オブジェクトを表す文字列です。

解説

JavaScript は toString メソッドをオブジェクトをプリミティブ値に変換するために呼び出します。 toString を呼び出す必要があるのは稀です。 JavaScript は、プリミティブ値が期待されるオブジェクトに遭遇すると、自動的に toString メソッドを呼び出します。

このメソッドは文字列変換によって優先的に呼び出されますが、数値変換プリミティブ変換valueOf() を優先的に呼び出します。ただし、基底の valueOf() メソッドはオブジェクトを返すので、オブジェクトが valueOf() をオーバーライドしない限り、通常は最後に toString() メソッドが呼び出されます。例えば、 +[1]1 を返しますが、これは toString() メソッドが "1" を返し、それが数値に変換されるからです。

Object.prototype を継承するすべてのオブジェクト( null プロトタイプオブジェクトを除くすべてのオブジェクト)は toString() メソッドを継承します。独自オブジェクトを作成するときは、toString() をオーバーライドして独自メソッドを呼び出し、独自オブジェクトを文字列値に変換できるようにします。また、[Symbol.toPrimitive]() メソッドを追加することもできます。このメソッドでは、変換処理をより細かく制御することができ、どの型の変換についても常に valueOf または toString よりも優先されます。

基底となる Object.prototype.toString() をオーバーライドされているオブジェクトで使用する(または nullundefined に対して呼び出す)には、 Function.prototype.call() または Function.prototype.apply() を呼び出す必要があり、最初の引数(thisArg と呼ばれる)として検査したいオブジェクトを渡します。

js
const arr = [1, 2, 3];

arr.toString(); // "1,2,3"
Object.prototype.toString.call(arr); // "[object Array]"

Object.prototype.toString() は、 "[object Type]" を返し、 Type のところがオブジェクト型になります。オブジェクトに値が文字列である Symbol.toStringTag プロパティがある場合、その値が Type として使用されます。 Map および Symbol を含む多くの組み込みオブジェクトには、 Symbol.toStringTag があります。 ES6 以前のオブジェクトの中には Symbol.toStringTag を持たないものもありますが、それでも特別なタグを持っています。これには次のようなものがあります(タグは下記で指定された型名と同じです)。

arguments オブジェクトは "[object Arguments]" を返します。それ以外のものはすべて、ユーザー定義クラスを含み、独自の Symbol.toStringTag をない限り、 "[object Object]" を返します。

Object.prototype.toString()null および undefined に対して呼び出すと、それぞれ [object Null] および [object Undefined] を返します。

独自オブジェクトの toString のオーバーライド

既定の toString() メソッドに代わって呼び出される関数を作ることができます。 toString() メソッドは文字列を返す必要があります。オブジェクトを返し、そのメソッドが型変換の際に暗黙的に呼び出された場合、その結果は無視され、代わりに相対メソッド valueOf() の値が使われます。これらのメソッドのどちらもがプリミティブ値を返さない場合は TypeError が発生します。

以下のコードは Dog クラスを定義しています。

js
class Dog {
  constructor(name, breed, color, sex) {
    this.name = name;
    this.breed = breed;
    this.color = color;
    this.sex = sex;
  }
}

このカスタムオブジェクト上で toString() メソッドを呼び出した場合、メソッドは Object から継承された既定値を返します。

js
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");

theDog.toString(); // "[object Object]"
`${theDog}`; // "[object Object]"

以下のコードは既定の toString() メソッドを上書きします。このメソッドはオブジェクトの name, breed, color, sex を格納した文字列を生成します。

js
class Dog {
  constructor(name, breed, color, sex) {
    this.name = name;
    this.breed = breed;
    this.color = color;
    this.sex = sex;
  }
  toString() {
    return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
  }
}

上記のコードの中で、 Dog が文字列の文脈で使用されるたびに、 JavaScript は自動的に toString() 関数を呼び出し、以下の文字列を返します。

js
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");

`${theDog}`; // "Dog Gabby is a female chocolate Lab"

toString() を使用してオブジェクトクラスの判別

toString() はすべてのオブジェクトに対し、(既定では) そのクラスを得るために使用することができます。

js
const toString = Object.prototype.toString;

toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
// Math には Symbol.toStringTag がある
toString.call(Math); // [object Math]

toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

このような toString() の使用は信頼できません。オブジェクトは Object.prototype.toString() の動作を Symbol.toStringTag プロパティを定義することで変更でき、それによって次のように予想外の動作になります。

js
const myDate = new Date();
Object.prototype.toString.call(myDate); // [object Date]

myDate[Symbol.toStringTag] = "myDate";
Object.prototype.toString.call(myDate); // [object myDate]

Date.prototype[Symbol.toStringTag] = "prototype polluted";
Object.prototype.toString.call(new Date()); // [object prototype polluted]

仕様書

Specification
ECMAScript Language Specification
# sec-object.prototype.tostring

ブラウザーの互換性

BCD tables only load in the browser

関連情報