内容へ移動
Cat Paw Software
ユーザ用ツール
ログイン
サイト用ツール
検索
ツール
文書の表示
以前のリビジョン
バックリンク
最近の変更
メディアマネージャー
サイトマップ
ログイン
>
最近の変更
メディアマネージャー
サイトマップ
トレース:
•
file
•
snappy
•
bookmarklet
•
docker-compose
ecmascript:class
この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。
<markdown> # class ## クラス構文 ```javascript class Test { // 静的フィールド static version = '1.0.0'; // 静的メソッド static info() { // 注意 staticコンテキストでのthis.nameはクラス名を指す(`#name`ではない) return `${this,name} class, version ${this.version}` } // privateフィールド #name = ''; // コンストラクタ constructor(v) { this.#name = v; } // メソッド getMessage() { return 'Hello from ${this.#name}' } // getter get name() { return this.#name; } // setter set name(v) { this.#name = v; } } ``` ## 継承 ```javascript class Test2 extends Test { // 拡張メソッド print() { console.log(this.getMessage()); } } ``` ## 関数とnew ここからはマニア向けのディープな話になる。JSの関数はコンストラクタとして機能し、new演算子によって新しいオブジェクトを生成できる ```javascript function Fuga(x) { this.x = x; } const fuga = new Fuga(1); console.log(typeof Fuga); // => function // 普通の関数としても呼べる Fuga(); ``` 以下のコードは実は上記のコードとほぼ同等。class構文で定義したクラスは実は関数なのである。このような関数はコンストラクタ関数と呼ばれる ```javascript class Fuga { constructor(x) { this.x = x; } } const fuga = new Fuga(1); console.log(typeof Fuga); // => function // ただしclassで定義した関数は直接呼べないように制限がかかっている Fuga(); // TypeError: Class constructor Fuga cannot be invoked without 'new' ``` ※ ただしfunctionによるコンストラクタ定義は過去のコードとの互換性のために残されているので現在は非推奨でありclassキーワードを使うべき これは何を意味しているかというとclassと銘打っているが、その実体はクラスではないということだ。クラスのような振る舞いはprototype chainという仕組みで行われている。 ## constructorプロパティ 生成されたオブジェクトはconstructorというプロパティを持っている。これは自身を生成したコンストラクタ関数への参照である。 ```javascript class Hoge { constructor(name) { this.name = name; } getName() { return this.name; } } const h = new Hoge(1) console.log(h,constructor === Hoge); // => true const h2 = new h.constructor(2); // newすることもできる ``` ## prototypeプロパティ コンストラクタ関数はprototypeというプロパティを持っている ```javascript console.log(Hoge.prototype); ``` classで定義したメソッドは、このprototypeプロパティが持っている。 ```javascript console.log(Hoge.prototype,getName); // => [function getName] console.log(Hoge.prototype,getName.call({ name: "にゃん" })); // => にゃん ``` コンストラクタ関数を通して生成されたオブジェクトは`__proto__`というプロパティを持っており、コンストラクタ関数のprototypeにアクセスできる ```javascript console.log(h.__proto__.getName); // => [function getName] ``` `h.__proto__`も`__proto__`を持っている。このようなprototypeの連鎖を**prototype chain**と呼ぶ ```javascript console.log(h.__proto__); // => {} console.log(h.__proto__.__proto__); // => [Object: null prototype] {} ``` 何も継承していないクラスの場合prototype chainは2つで終わりだが、継承すると継承した回数だけprototype chainは長くなる。 prototype chainはメソッドの呼び出しに関係している。例えば`x.m()`というコードを実行すると次のようにメソッドが検索される 1. `x`自身プロパティ一覧からmという名前のプロパティを探し、見つかったらメソッドとして実行する。なければ2へ 2. `x,__proto__`のプロパティ一覧からmという名前の・・・、なければ3へ 3. `x.__proto__.__proto__`のプロパティ一覧からmという名前の・・・、なければ4へ 4. prototype chainの末端まで到達しても見つからない場合はTypeErrorとなる </markdown>
ecmascript/class.txt
· 最終更新:
2025/09/09 16:30
by
nullpon
ページ用ツール
文書の表示
以前のリビジョン
バックリンク
文書の先頭へ