javascript:class
差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン | |||
| javascript:class [2016/01/19 07:56] – [継承] nullpon | javascript:class [2025/09/09 16:23] (現在) – 削除 nullpon | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | ====== クラス ====== | ||
| - | ===== クラス構文 ===== | ||
| - | |||
| - | ECMAScript 2015からクラス構文が導入された。 | ||
| - | |||
| - | <code javascript> | ||
| - | 'use strict'; | ||
| - | |||
| - | class Hoge { | ||
| - | // コンストラクタ | ||
| - | constructor(val) { | ||
| - | this._value = val | ||
| - | } | ||
| - | |||
| - | // メソッド | ||
| - | print() { | ||
| - | console.log(this._value); | ||
| - | } | ||
| - | | ||
| - | // ゲッター | ||
| - | get value() { | ||
| - | return this._value; | ||
| - | } | ||
| - | | ||
| - | // セッター | ||
| - | set value(val) { | ||
| - | this._value = val; | ||
| - | } | ||
| - | } | ||
| - | |||
| - | var hoge = new Hoge(1); | ||
| - | |||
| - | hoge.print(); | ||
| - | |||
| - | hoge.value = 2; | ||
| - | |||
| - | console.log(hoge.value) | ||
| - | </ | ||
| - | |||
| - | これは以前のprototypeによるクラス定義のシンタックスシュガーにすぎず、Hogeは関数オブジェクトとして定義されている。 | ||
| - | |||
| - | < | ||
| - | typeof(Hoge); | ||
| - | </ | ||
| - | |||
| - | ただし関数としての呼び出しには制限がかけられており、newを付けずに呼び出すとエラーになる。 | ||
| - | |||
| - | < | ||
| - | Hoge(); | ||
| - | </ | ||
| - | |||
| - | ==== 継承 ==== | ||
| - | |||
| - | < | ||
| - | class Fuga extends Hoge { | ||
| - | // メソッド | ||
| - | print2() { | ||
| - | console.log(this._value * 2); | ||
| - | } | ||
| - | } | ||
| - | |||
| - | var fuga = new Fuga(3); | ||
| - | |||
| - | fuga.print(); | ||
| - | fuga.print2(); | ||
| - | </ | ||
| - | |||
| - | |||
| - | ==== staticメソッド ==== | ||
| - | |||
| - | < | ||
| - | class Piyo extends Hoge{ | ||
| - | // メソッド | ||
| - | static piyo() { | ||
| - | console.log(' | ||
| - | } | ||
| - | } | ||
| - | |||
| - | Piyo.piyo(); | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== prototypeによるクラス定義 ===== | ||
| - | |||
| - | ここからはES5以前の話 | ||
| - | |||
| - | ==== コンストラクタ ==== | ||
| - | |||
| - | 関数はコンストラクタとして働く。コンストラクタとして使う関数は、慣例として大文字で名前を定義する。 | ||
| - | |||
| - | <code javascript> | ||
| - | // クラス定義1 | ||
| - | // コンストラクタ関数 | ||
| - | function Greet() { | ||
| - | // プロパティの定義 | ||
| - | this.message = " | ||
| - | |||
| - | // メソッドの定義 | ||
| - | this.say = function() { | ||
| - | return this.message; | ||
| - | }; | ||
| - | } | ||
| - | |||
| - | // インスタンスの生成 | ||
| - | var greet = new Greet(); | ||
| - | |||
| - | // メソッドの呼び出し | ||
| - | greet.say(); | ||
| - | |||
| - | </ | ||
| - | |||
| - | ==== constructor プロパティ ==== | ||
| - | |||
| - | 生成されたインスタンスは constructor というプロパティを持っており、自分のコンストラクタにアクセスできる。 | ||
| - | |||
| - | <code javascript> | ||
| - | function Greet() { | ||
| - | // ... | ||
| - | } | ||
| - | |||
| - | var greet = new Greet(); | ||
| - | |||
| - | greet.constructor; | ||
| - | </ | ||
| - | |||
| - | ==== プロトタイプ ==== | ||
| - | |||
| - | コンストラクタは prototype というプロパティを持っている。 | ||
| - | |||
| - | <code javascript> | ||
| - | function Greet() { | ||
| - | // ... | ||
| - | } | ||
| - | Greet.prototype; | ||
| - | |||
| - | var greet = new Greet(); | ||
| - | greet.constructor.prototype; | ||
| - | </ | ||
| - | |||
| - | new演算子で作成されたインスタンスは、自分のコンストラクタの prototype が持っているプロパティやメソッドに、あたかも自分のメソッドやプロパティであるかのようにアクセスできる。 | ||
| - | |||
| - | よって prototype にプロパティやメソッドを定義してインスタンスで利用することができる。ただし全てのインスタンスで共有されてしまうため、メソッドのみ prototype に定義するのが一般的である。 | ||
| - | |||
| - | <code javascript> | ||
| - | // クラス定義2 | ||
| - | function Greet(message) { | ||
| - | // プロパティ定義 | ||
| - | this.message = message; | ||
| - | } | ||
| - | |||
| - | // メソッド定義 | ||
| - | Greet.prototype.say = function() { | ||
| - | return this.message | ||
| - | } | ||
| - | |||
| - | var greet = new Greet(" | ||
| - | |||
| - | greet.say(); | ||
| - | </ | ||
| - | |||
| - | prototypeを丸ごと上書きして置き換えることもできる。 | ||
| - | |||
| - | <code javascript> | ||
| - | // クラス定義3 | ||
| - | function Greet(message) { | ||
| - | // プロパティ定義 | ||
| - | this.message = message; | ||
| - | } | ||
| - | |||
| - | Greet.prototype = { | ||
| - | say: function() { | ||
| - | return this.message | ||
| - | } | ||
| - | }; | ||
| - | |||
| - | var greet = new Greet(" | ||
| - | |||
| - | greet.say(); | ||
| - | </ | ||
| - | |||
| - | ==== __proto__ プロパティ ==== | ||
| - | |||
| - | new演算子で作成されたインスタンスは、内部的に < | ||
| - | |||
| - | <code javascript> | ||
| - | var greet = new Greet(); | ||
| - | greet.__proto__ === Greet.prototype; | ||
| - | greet.__proto__ === greet.constructor.prototype; | ||
| - | </ | ||
| - | |||
| - | これは隠しプロパティ扱いの場合もあるので、実際のプログラミングでは constructor.prototype を使うのがよい。 | ||
| - | |||
| - | ===== プロトタイプチェーン ===== | ||
| - | |||
| - | インスタンスは、< | ||
| - | |||
| - | あるインスタンスに対してメソッドAを呼び出したとき、もし、インスタンスがメソッドAを持っておらず、プロトタイプがメソッドAを持っていれば、プロトタイプのメソッドAが呼び出される。もしプロトタイプもメソッドAを持っていなければ、プロトタイプのプロトタイプがメソッドAを持っているか探す。 | ||
| - | |||
| - | この仕組みをプロトタイプチェーンと呼ぶ。プロトタイプチェーンを使うと継承に似たことができる。 | ||
| - | |||
| - | <code javascript> | ||
| - | function Greet() { | ||
| - | this.message = " | ||
| - | } | ||
| - | Greet.prototype.say = function() { | ||
| - | return this.message | ||
| - | } | ||
| - | |||
| - | function NightGreet() { | ||
| - | this.message = "good night"; | ||
| - | } | ||
| - | NightGreet.prototype = new Greet(); | ||
| - | |||
| - | function JpNightGreet() { | ||
| - | this.message = " | ||
| - | } | ||
| - | NightGreet.prototype = new NightGreet(); | ||
| - | |||
| - | |||
| - | // JpNightGreet型のインスタンス生成 | ||
| - | var jpNightGreet = new JpNightGreet(); | ||
| - | |||
| - | // Greet型の(プロトタイプのプロトタイプ)メソッドsayが呼び出される | ||
| - | jpNightGreet.say(); | ||
| - | </ | ||
| - | |||
| - | プロトタイプチェーンを最後までさかのぼると、最終的にはObjectになる。よってObjectのメソッドは全てのインスタンスから呼び出すことができる。(といってもvalueOfとtoString、toSourceぐらいしか無い) | ||
javascript/class.1453190192.txt.gz · 最終更新: by nullpon