---
author: azu
description: "JavaScriptのプリミティブ型の値がビルトインオブジェクトのメソッドなどを呼び出せる仕組みとしてのラッパーオブジェクトを紹介します。プリミティブ型からオブジェクトとどのように実行時に変換されているのを確認できます。"
sponsors: []
---

# ラッパーオブジェクト {#wrapper-object}

JavaScriptのデータ型はプリミティブ型とオブジェクトに分けられます（詳細は「[データ型とリテラル][]」を参照）。

次のコードでは文字列リテラルでプリミティブ型の値である文字列を定義しています。
プリミティブ型の値である文字列は`String`オブジェクトのインスタンスではありません。
しかし、プリミティブ型の文字列においても、`String`オブジェクトのインスタンスメソッドである`toUpperCase`メソッドを呼び出せます。

{{book.console}}
```js
// Stringの`toUpperCase`メソッドを呼び出せる
"string".toUpperCase(); // => "STRING"
```

プリミティブ型である文字列が`String`のインスタンスメソッドを呼び出せるのは一見不思議です。

この章では、プリミティブ型の値がなぜオブジェクトのメソッドを呼び出せるのかについて解説します。

## プリミティブ型とラッパーオブジェクト {#primitive-type-and-wrapper-object}

<!--　textlint-disable preset-ja-technical-writing/max-ten -->

プリミティブ型のデータのうち、真偽値（Boolean）、数値（Number） 、BigInt、文字列（String）、シンボル（Symbol）にはそれぞれ対応するオブジェクトが存在します。たとえば、文字列に対応するオブジェクトとして、`String`オブジェクトがあります。

この`String`オブジェクトを`new`することで`String`オブジェクトのインスタンスを作れます。

<!-- textlint-enable -->

{{book.console}}
```js
// "input value"の値をラップしたStringのインスタンスを生成
const str = new String("input value");
// StringのインスタンスメソッドであるtoUpperCaseを呼び出す
str.toUpperCase(); // => "INPUT VALUE"
```

このようにインスタンス化されたものは、プリミティブ型の値を包んだ（ラップした）オブジェクトと言えます。
そのため、このようなオブジェクトをプリミティブ型の値に対しての**ラッパーオブジェクト**と呼びます。

ラッパーオブジェクトとプリミティブ型の対応は次のとおりです。

| ラッパーオブジェクト | プリミティブ型 | 例               |
| -------------------- | -------------- | ---------------- |
| `Boolean`            | 真偽値         | `true`や`false`  |
| `Number`             | 数値           | `1`や`2`         |
| `BigInt`             | BigInt        | `1n`や`2n`        |
| `String`             | 文字列         | `"文字列"`       |
| `Symbol`             | シンボル       | `Symbol("説明")` |


注記: `undefined`と`null`に対応するラッパーオブジェクトはありません。

<!-- 出典: ToStringの対応するオブジェクト

- https://tc39.es/ecma262/#sec-toobject
- https://tc39.es/ecma262/#sec-get-o-p

 -->

注意点として、ラッパーオブジェクトは名前のとおりオブジェクトです。
そのため、次のように`typeof`演算子でラッパーオブジェクトを見ると`"object"`です。

{{book.console}}
```js
// プリミティブの文字列は"string"型
const str = "文字列";
console.log(typeof str); // => "string"
// ラッパーオブジェクトは"object"型
const stringWrapper = new String("文字列");
console.log(typeof stringWrapper); // => "object"
```

## プリミティブ型の値からラッパーオブジェクトへの自動変換 {#convert-primitive-to-wrapper}

JavaScriptでは、プリミティブ型の値に対してプロパティアクセスするとき、自動で対応するラッパーオブジェクトに変換されます。
たとえば`"string"`という文字列は、自動的に`new String("string")`のようなラッパーオブジェクトへ変換されています。
これにより、プリミティブ型の値である文字列が`String`のインスタンスメソッドを呼び出せるようになります。

```js
const str = "string";
// プリミティブ型の値に対してメソッド呼び出しを行う
str.toUpperCase();
// `str`へアクセスする際に"string"がラッパーオブジェクトへ変換され、
// ラッパーオブジェクトはStringのインスタンスなのでメソッドを呼び出せる
// つまり、上のコードは下のコードと同じ意味である
(new String(str)).toUpperCase();
```

このように、プリミティブ型の値からラッパーオブジェクトへの変換は自動的に行われます。[^1]

一方、明示的に作成したラッパーオブジェクトからプリミティブ型の値を取り出すこともできます。

`ラッパーオブジェクト.valueOf`メソッドを呼び出すことで、ラッパーオブジェクトから値を取り出せます。
たとえば、次のように文字列のラッパーオブジェクトから`valueOf`メソッドで文字列を取り出せます。

{{book.console}}
```js
const stringWrapper = new String("文字列");
// プリミティブ型の値を取得する
console.log(stringWrapper.valueOf()); // => "文字列"
```

JavaScriptには、リテラルを使ったプリミティブ型の文字列とラッパーオブジェクトを使った文字列オブジェクトがあります（真偽値や数値についても同様です）。
この2つを明示的に使い分ける利点はないため、常にリテラルを使うことを推奨します。
理由として次の3つが挙げられます。

- 必要に応じて、プリミティブ型の文字列は自動的にラッパーオブジェクトに変換されるため
- `new String("string")`のようにラッパーオブジェクトのインスタンスを扱う利点がないため
- ラッパーオブジェクトを`typeof`演算子で評価した結果が、プリミティブ型ではなく`"object"`となり混乱を生むため

これらの理由などから、プリミティブ型のデータにはリテラルを使います。
常にリテラルを使うことでラッパーオブジェクトを意識する必要がなくなります。

```js
// OK: リテラルを使う
const str = "文字列";
// NG: ラッパーオブジェクトを使う
const stringWrapper = new String("文字列");
```

## まとめ {#wrapper-object-summary}

この章では、プリミティブ型の値がなぜメソッド呼び出しできるのかについて解説しました。
その仕組みの背景にはプリミティブ型に対応したラッパーオブジェクトの存在があります。
プリミティブ型の値のプロパティへアクセスする際に、自動的にラッパーオブジェクトへ変換されることでメソッド呼び出しなどが可能となっています。

「JavaScriptはすべてがオブジェクトである」と言われることがあります。
プリミティブ型はオブジェクトではありませんが、プリミティブ型に対応したラッパーオブジェクトが用意されています（`null`と`undefined`を除く）。
そのため、「すべてがオブジェクトのように見える」というのが正しい認識となるでしょう。


[データ型とリテラル]: ../data-type/README.md  "データ型とリテラル"
[^1]: このようなプリミティブ型からオブジェクト型への変換はボックス化（ボクシング）、逆にオブジェクト型からプリミティブ型への変換はボックス化解除（アンボクシング）と呼ばれます。
