フロントエンド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 8.0 のインデックス スキップ スキャン

序文MySQL 8.0.13 では、インデックス スキップ スキャン (インデックス ジャンプ スキ...

js の一般的でない演算子と演算子の概要

一般的な演算子と JavaScript の演算子の概要カテゴリオペレーター算術演算子+、–、*、/、...

MySQLデータベースのリアルタイムバックアップの知識ポイントを詳しく解説

序文リアルタイムのデータベース バックアップの必要性は非常に一般的です。MySQL 自体はレプリケー...

Vue でのルーティングガードの具体的な使用法

目次1. グローバルガード1.1 グローバルフロントガード1.2 グローバルポストルートガード1.3...

Nginx を使用して rtmp ライブ サーバーを実行する方法

今回は、コンピューターや携帯電話用の rtmp ライブ ブロードキャスト サーバーを設定し、ライブ ...

Linux での mysql および mysql.sock のインストールに関する問題

最近、Linux に Aphace、mysql、php をインストールするときに多くの問題に遭遇しま...

CentOS で新しいユーザーを作成し、キーログインを有効にする方法

目次新しいユーザーを作成する新規ユーザーを承認する新規ユーザーのSSHキーログインを有効にする他のS...

MySQLデータベースがNULLを可能な限り避ける理由

MySQL の多くのテーブルには、NULL が列のデフォルト属性であるため、アプリケーションが NU...

Dockerデータ管理とネットワーク通信の使用

Docker をインストールし、Docker コアとインストールを通じて簡単な操作を実行できます。 ...

Linux ユーザー スクリプトの作成/推測ゲーム/ネットワーク カード トラフィック監視の紹介

目次1. ユーザーが作成したスクリプト2. 単語当てゲーム3. ネットワークカードのトラフィック監視...

MySQLカバーインデックスの利点

一般的な提案は、WHERE 条件のインデックスを作成することですが、これは実際には一方的です。インデ...

mysql 10進データ型変換の実装

最近、次のデータ型のデータベースに遭遇しました:decimal(14,4)発生した問題は次のとおりで...

Centos7 で keepalived ログを別のパスに設定する方法の詳細な説明

Keepalived のインストール: cd <keepalived_sourcecode_p...

MySQLのインストールと設定方法のグラフィックチュートリアル(CentOS7)

1. システム環境[root@localhost ホーム]# cat /etc/redhat-re...