フロントエンドJavaScriptのクラス

フロントエンドJavaScriptのクラス

1. クラス

クラスはオブジェクトを作成するためのテンプレートです。 JavaScriptでオブジェクト インスタンスを生成する方法はコンストラクターを介して行われますが、これは主流のオブジェクト指向言語 ( javaC# ) の記述方法とは次の通り大きく異なります。

関数 Point(x, y) {
  this.x = x;
  y = y;
}

Point.prototype.toString = 関数 () {
  '(' + this.x + ', ' + this.y + ')' を返します。
};

var p = 新しいポイント(1, 1);

ES6Java言語に近い記述方法を提供し、オブジェクトのテンプレートとしてClass(類)の概念を導入します。クラスは、class キーワードを使用して定義できます。

次のように: constructor()は構築メソッドであり、これはインスタンス オブジェクトを表します。

クラス Point {
  コンストラクタ(x, y) {
    this.x = x;
    y = y;
  }

  文字列を渡す
    '(' + this.x + ', ' + this.y + ')' を返します。
  }
}

クラスのデータ型は関数であり、それ自体は関数を指すコンストラクターです。

// ES5 関数宣言 function Point() {
 //...
}

// ES6 クラス宣言 class Point {
  //....
  コンストラクタ() {
  }
}
typeof Point // "関数"
Point === Point.prototype.constructor // true

クラスで定義されたメソッドはPoint.prototypeにアタッチされるため、クラスは構文上の糖衣のみを提供し、本質は依然としてプロトタイプ チェーン呼び出しのままです。

クラス Point {
  コンストラクタ(x, y) {
    this.x = x;
    y = y;
  }

  文字列を渡す
    '(' + this.x + ', ' + this.y + ')' を返します。
  }
}

ポイント.プロトタイプ = {
  //....
  文字列を変換する()
}
var p = 新しいポイント(1, 1);
p.toString() // (1,1)

クラスを定義する別の方法はクラス式を使うことである。

// 名前のない/匿名クラス let Point = class {
  コンストラクタ(x, y) {
    this.x = x;
    y = y;
  }
};
Point.name // ポイント

関数宣言とクラス宣言には重要な違いがあります。関数宣言はホイストされますが、クラス宣言はホイストされません。

> let p = new Point(); // 昇格してもエラーは報告されません> function Point() {}
> 
> let p = new Point(); // エラー、ReferenceError
> クラス Point {}
>

1.1 コンストラクタ()

constructor()メソッドはクラスのデフォルト メソッドであり、 newインスタンス オブジェクトを生成するときに自動的に呼び出されます。

クラスにはconstructor()メソッドが必要です。明示的に定義されていない場合、エンジンはデフォルトで空のconstructor()を追加します。

constructor()メソッドは、デフォルトでインスタンス オブジェクト (つまりthis ) を返します。

クラス Point {
}

// クラス Point を自動的に追加します {
  コンストラクタ() {}
}

1.2 ゲッターとセッター

ES5と同様に、クラス内でgetキーワードとsetキーワードを使用して、プロパティの保存関数と取得関数を設定し、プロパティの保存とアクセスの動作をインターセプトできます。

クラスユーザー{
  コンストラクタ(名前) {
    this.name = 名前;
  }

  名前を取得する() {
    this.name を返します。
  }

  名前(値)を設定する{
    this.name = 値;
  }
}

1.3 これ

クラス メソッド内のthisは、デフォルトでクラスのインスタンスを参照します。 this を使用してメソッドを呼び出す場合は、 obj.method()を使用する必要があります。そうしないと、エラーが報告されます。

クラスユーザー{
  コンストラクタ(名前) {
    this.name = 名前;
  }
  プリント名(){
    console.log('名前は' + this.nameです)
  }
}
定数ユーザー = 新しいユーザー('jack')
user.printName() // 名前はjackです
const { printName } = ユーザー;
printName() // エラー 未定義のプロパティを読み取ることができません (読み取り 'name')

エラーなしで個別に呼び出す場合、1 つの方法はコンストラクターでbind(this)を呼び出すことです。

クラスユーザー{
  コンストラクタ(名前) {
    this.name = 名前;
    this.printName = this.printName.bind(this);
  }
  プリント名(){
    console.log('名前は' + this.nameです)
  }
}
定数ユーザー = 新しいユーザー('jack')
const { printName } = ユーザー;
printName() // 名前はジャック

bind(this)新しい関数を作成し、渡された this を関数が呼び出されたときのコンテキストとして使用します。

さらに、矢印関数内の this は常にそれが定義されているオブジェクトを参照するため、矢印関数を使用することもできます。

クラスユーザー{
  コンストラクタ(名前) {
    this.name = 名前;
  }
  プリント名 = () => {
    console.log('名前は' + this.nameです)
  }
}
定数ユーザー = 新しいユーザー('jack')
const { printName } = ユーザー;
printName() // 名前はジャック

1.4 静的プロパティ

静的プロパティは、インスタンス オブジェクトthisで定義されたプロパティではなく、クラス自体のプロパティを参照します。

クラスユーザー{
}

ユーザー.prop = 1;
ユーザー.prop // 1

1.5 静的メソッド

クラス内に静的メソッドを定義できます。メソッドはオブジェクト インスタンスによって継承されず、クラスを通じて直接呼び出されます。

thisクラスを指すために静的メソッドで使用されます。

クラス Utils {
  静的printInfo() {
     this.info();
  }
  静的情報() {
     コンソールにログ出力します。
  }
}
Utils.printInfo() // こんにちは

メソッドの呼び出しスコープの制限(private や public など)については、 ES6ではまだ提供されていません。これらは一般に、規則を通じて採用されます。たとえば、メソッドの前にアンダースコア _print() を追加すると、プライベート メソッドであることを示します。

2. 継承

Javaでは、クラスの継承はextendsを通じて実装されます。 ES6では、 extendsを通じてクラスを継承することもできます。

継承する場合、サブクラスはconstructorメソッドでsuperメソッドを呼び出す必要があります。そうしないと、新しいインスタンスを作成するときにエラーが報告されます。

クラスPoint3DはPointを拡張します{
  コンストラクタ(x, y, z) {
    super(x, y); // 親クラスのコンストラクター(x, y)を呼び出す
    this.z = z;
  }

  文字列を渡す
    return super.toString() + ' ' + this.z; // 親クラスのtoString()を呼び出す
  }
}

親クラスの静的メソッドは子クラスにも継承されます。

クラス親{
  静的情報() {
    console.log('こんにちは世界');
  }
}

クラスChildはParentを拡張します{
}

Child.info() // こんにちは世界

2.1 スーパーキーワード

super関数は、親クラスのコンストラクターを表すサブクラスのコンストラクター内で 1 回実行する必要があります。

クラス 親 {}

クラスChildはParentを拡張します{
  コンストラクタ() {
    素晴らしい();
  }
}

サブクラスの通常のメソッドでsuperを介して親クラスのメソッドを呼び出す場合、メソッド内のthisは現在のサブクラスのインスタンスを指します。

クラス親{
  コンストラクタ() {
    1.x = 1; を出力します。
    これ.y = 10
  }
  親を印刷する(){
    コンソールにログ出力します。
  }
  印刷(){
    コンソールにログ出力します。
  }
}

クラスChildはParentを拡張します{
  コンストラクタ() {
    素晴らしい();
    2 を 0 にします。
  }
  m() {
    スーパープリント();
  }
}

c = new Child();
c.printParent() // 10
センチメートル() // 2

2.2 _proto_ とプロトタイプ

初めてJavaScriptを学ぶときは、 _proto_prototype混同しがちです。まず、各JSオブジェクトはプロトタイプ オブジェクトに対応し、プロトタイプ オブジェクトからプロパティとメソッドを継承することがわかります。

  • prototypeは、組み込みオブジェクトおよび関数のプロパティです。これはオブジェクトへのポインタです。このオブジェクトの目的は、すべてのインスタンスで共有されるプロパティとメソッドを格納することです (このオブジェクトをプロトタイプ オブジェクトと呼びます)。
  • _proto_すべてのオブジェクトにはこのプロパティがあり、通常は対応するコンストラクターのprototypeプロパティを指します。

以下はプロトタイプを持つ組み込みオブジェクトの一部です。

上記の説明に従って、次のコードを見てください

var obj = {} // var obj = new Object() と同等

// obj.__proto__ は Object コンストラクタのプロトタイプを指します
obj.__proto__ === Object.prototype // true 

// obj.toString は Object.prototype から継承されたメソッドを呼び出します obj.toString === obj.__proto__.toString // true

// 配列 var arr = []
arr.__proto__ === Array.prototype // true

functionオブジェクトの場合、宣言された各functionにはprototype__proto__属性の両方があります。作成されたオブジェクトの属性__proto__は関数prototypeを指し、関数の__proto__は組み込み関数オブジェクト (Function) のprototypeを指します。

関数 Foo(){}
var f = new Foo();
f.__proto__ === Foo.prototype // 真
Foo.__proto__ === Function.prototype // true

2.3 継承における__proto__

コンストラクター関数の構文糖衣として、クラスにはprototype__proto__プロパティの両方があるため、同時に 2 つの継承チェーンが存在します。

  • サブクラスの__proto__プロパティはコンストラクターの継承を示し、常に親クラスを指します。
  • サブクラスのプロトタイプ プロパティの__proto__プロパティはメソッドの継承を示し、常に親クラスのprototypeプロパティを指します。
クラス親{
}

クラスChildはParentを拡張します{
}

Child.__proto__ === Parent // true
Child.prototype.__proto__ === Parent.prototype // true

2.4 継承されたインスタンス内の__proto__

サブクラス インスタンスの__proto__プロパティは、サブクラス コンストラクターのprototypeを指します。

サブクラス インスタンスの__proto__プロパティの__proto__プロパティは、親クラス インスタンスの__proto__プロパティを指します。つまり、サブクラスのプロトタイプのプロトタイプは、親クラスのプロトタイプです。

クラス親{
}

クラスChildはParentを拡張します{
}

var p = 新しい親();
var c = 新しい子();

c.__proto__ === p.__proto__ // 偽
c.__proto__ === Child.prototype // true
c.__proto__.__proto__ === p.__proto__ // 真

3. まとめ

フロントエンドJavaScriptclassに関するこの記事はこれで終わりです。JavaScript のJavaScript classより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • js 学習ノート: class、super、extends キーワード
  • JavaScript オブジェクト指向クラス継承ケースの説明
  • JSでES6クラスの使い方をすぐにマスター
  • JS タブ プラグインを作成する 2 つの方法 (jQuery とクラス)
  • JSを使用したクラス名の追加と削除の詳細な説明

<<:  docker を使用して Redis マスター/スレーブを構築する方法

>>:  データベースインデックスの知識ポイントの概要

推薦する

MySQLクエリ書き換えプラグインの使用

クエリ書き換えプラグインMySQL 5.7.6 以降、MySQL Server は、サーバーが実行す...

デザインスキルを向上させる良い方法

いわゆる才能(左脳と右脳)つまり、芸術的な才能があるかどうかは、人間の左脳と右脳の分業によって主に決...

MySQL でよく使用される SQL 文を表示する (詳細な説明)

#mysql -uroot -pパスワードを入力してくださいmysql> show full...

Dockerアーキテクチャ入門

Docker には 3 つの基本概念が含まれています。イメージ: Docker イメージはルート フ...

CentOS 6.5 インストール mysql5.7 チュートリアル

1. 新機能MySQL 5.7 はエキサイティングなマイルストーンです。デフォルトの InnoDB ...

VUE ユニアプリテンプレート構文についての簡単な説明

1.v-bind(略称:)コンポーネント プロパティのデータで定義されたデータ変数を使用するか、コン...

MySQLステートメントを監視する方法の詳細な説明

クイックリーディングSQL ステートメントを監視する必要があるのはなぜか、監視方法と監視手段について...

jQueryは、マウスをドラッグしてdivの位置とサイズを変更する方法を実装しています。

Windows フォームと同様の効果を得るには、中央をドラッグして div の位置を変更し、端をド...

CentOS7 (YUM) での MySQL 5.7 のインストールと設定のチュートリアル

インストール環境: CentOS7 64ビット、MySQL5.7 1. YUMソースを設定するMyS...

デザインリファレンス 美しく独創的なブログデザイン

以下にリストされているすべてのブログはオリジナルであり、独自にデザインされています。これらは、他者が...

中国の専門ではない:文化の違いの中でのウェブ開発

Web デザインと開発は大変な作業なので、少数の人だけを対象に設計しないでください。これは外国人が...

CSS チュートリアル: CSS 属性メディア タイプ

スタイルシートの最も重要な機能の 1 つは、ページ、画面、電子シンセサイザーなどの複数のメディアに適...

Vue の foreach 配列と js の traversal 配列の書き方の説明

Vue foreach配列を記述し、jsで配列をトラバースする方法シナリオVueでAxiosを使用し...

winx64 での mysql5.7.19 の基本的なインストール プロセス (詳細)

1. ダウンロード参考: https://www.jb51.net/softs/451120.ht...

Linuxのバージョン情報を復号化する方法

Linux バージョンに関する情報を表示および解釈するのは、見た目よりも少し複雑です。単純なバージョ...