JavaScript はオブジェクト指向言語です。JavaScript を書くときにはほとんど100%の人がオブジェクト思考の恩恵に預かっています。
「オブジェクト指向といえばクラスとか継承でしょ? 使わなくてもコード書けるじゃん!」と思うかもしれません。
こちらのコードをご覧ください👀
const text = "Hello, world!";
console.log(text.toUpperCase()); // => "HELLO, WORLD!"
console.log(text.length); // => 13
.toUpperCase
は関数として実行されているのでメソッドですね。
.length
は値として割り振られた13を返しているだけなのでプロパティです。
あれ、だけどメソッドやプロパティは本来、オブジェクトの機能のはずですよね。なぜ文字列で使えるのでしょう?
この記事では JavaScript の組み込みメソッドやプロパティがどのように成り立っているかを解説していきます。
▼ オブジェクト指向の基本についてはこちらの記事で扱っているのでよければご覧ください
※ この記事では区別のため String オブジェクト(後述)を String オブジェクト、通常使っているような String 型のデータ / String オブジェクトから生成されたものを「文字列」と呼びます
メソッドとプロパティ
前提としてメソッドとプロパティはどちらもオブジェクトに属するものです。
const kinako = {
name: "kinako",
spieces: "cat",
getName: function () {
return this.name;
},
}
console.log(kinako.name); // -> 'kinako'
console.log(kinako.spieces); // -> 'cat'
console.log(kinako.getName()); // -> 'kinako'
上のコードの場合、 kinako オブジェクトの name、spieces はキーと値のペアであるプロパティです。 kinako.〇〇
の形でアクセスすると単に紐づけられた値を返してくれます。
そして kinako オブジェクトの getName はメソッドです。メソッドもキーと値を持っていますが、値として関数が入っているのでメソッドという名前になっています。こちらは呼び出して実行することで関数の実行結果を返してくれますね。
ラッパーオブジェクト
冒頭の答えですが、実は JavaScript には「String オブジェクト」 というものがあります。
JavaScript ではどんな文字列を宣言しても、同じように toUpperCase
や length
を使えますよね。そんな便利なメソッドやプロパティを初期装備しているのが String オブジェクトです。
↓ String オブジェクトをもとにすると、文字列はこんなふうに作成できます
let text = new String("Hello, world!");
console.log(text); // -> String {'Hello, world!'}
通常 const text = "Hello, world!";
のような形で宣言した文字列はオブジェクトじゃないので本来オブジェクトが持っているはずのメソッドやプロパティは使えないはずなのですが、メソッドやプロパティを使用する時だけ new String
で作成されたオブジェクトの形に自動で変換されているため、メソッドやプロパティを使用することができるのです。
String オブジェクトがあるように、数値のために Number オブジェクトが、真偽値のためには Boolean オブジェクトが…というふうに、「ここからメソッドやプロパティを引っ張ってこれるよ!」という特別なオブジェクトがいくつかあります。これらをラッパーオブジェクトと言います。
継承とプロトタイプ
親のオブジェクトから子のオブジェクトへ機能を引き継ぐことを「継承」と言います。String オブジェクトをもとに生成された文字列が同様のメソッド、プロパティを持っているのは継承の働きです。
JavaScript においてオブジェクトが互いに機能を継承するメカニズムをプロトタイプと言います。
オブジェクトは prototype
オブジェクトを持っており、この prototype
オブジェクトがテンプレートとなって子のオブジェクトが生成される仕組みとなっています。例えば String.prototype
とコンソールに打ち込んでみましょう。
こんなふうにすべてのオブジェクトで使えるメソッドが入っているはずです。
まとめ
- メソッドとプロパティは本来オブジェクトに属するものだが、文字列や数値など他の型でもラッパーオブジェクトのおかげで使うことができる
- ラッパーオブジェクトは
prototype
プロパティの中にメソッド、オブジェクトを持っており、継承の働きによって子オブジェクトはそれらを利用できる
参考資料
- String - JavaScript | MDN
- JavaScript | Stringオブジェクト
- JavaScript | ラッパーオブジェクトとプリミティブ型
- JavaScript での継承 - ウェブ開発を学ぶ | MDN
- Object のプロトタイプ - ウェブ開発を学ぶ | MDN
最後まで読んでくれた方ありがとうございます。僕もまとめていてだいぶ混乱したので一緒にきなこを見て癒されましょう。キャワイイ