オブジェクト指向プログラミングでは、クラスは、オブジェクトを作成し、状態(メンバ変数)および動作の実装(メンバ関数またはメソッド)の初期値を提供するための拡張可能なプログラムコードテンプレートである。
実際には、ユーザーや商品など、同じ種類の多くのオブジェクトを作成する必要があります。
章コンストラクタからすでに知っているように、operator”new”,new function
それを助けることができます。,
しかし、現代のJavaScriptには、オブジェクト指向プログラミングに役立つ素晴らしい新機能を導入する、より高度な”クラス”構造があります。
“クラス”構文
基本的な構文は次のとおりです。
class MyClass { // class methods constructor() { ... } method1() { ... } method2() { ... } method3() { ... } ...}
次に、new MyClass()
を使用して、リストされたすべてのメソッドで新しいオブジェクトを作成します。
constructor()
メソッドはnew
によって自動的に呼び出されるため、そこでオブジェクトを初期化できます。,
たとえば、
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// Usage:let user = new User("John");user.sayHi();
new User("John")
が呼び出されると、
- 新しいオブジェクトが作成されます。
constructor
指定された引数で実行され、それをthis.name
に割り当てます。…次に、user.sayHi()
のようなオブジェクトメソッドを呼び出すことができます。クラスメソッドの間にコンマを入れない初心者の開発者にとってよくある落とし穴は、クラスメソッドの間にコンマを入れることです。,
ここでの表記は、オブジェクトリテラルと混同しないでください。 クラス内では、カンマは必要ありません。
クラスとは何ですか?h2>
だから、正確には何ですか
class
? これはまったく新しい言語レベルの実体ではありません。魔法を明らかにして、クラスが本当に何であるかを見てみましょう。 それは多くの複雑な側面を理解するのに役立ちます。
JavaScriptでは、クラスは一種の関数です。,
ここでは、見てみましょう:
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// proof: User is a functionalert(typeof User); // function
class User {...}
構造が本当に何をしているのですか:- 、それはクラス宣言の結果になります。 関数コードは、
constructor
メソッドから取得されます(そのようなメソッドを記述しない場合は空とみなされます)。li> - は、
sayHi
などのクラスメソッドをUser.prototype
に格納します。,
new User
オブジェクトが作成された後、そのメソッドを呼び出すと、f.prototypeの章で説明したように、プロトタイプから取得されます。 したがって、オブジェクトはクラスメソッドに,のclass User
宣言として:構文糖だけでなく
class
は”構文糖”(読みやすくするように設計されていますが、新しいものは何も導入しません)であると言うことがあります。class
キーワードなしで実際に同じことを宣言することができるため、この定義の結果はほぼ同じです。
この定義の結果はほぼ同じです。—–, したがって、
class
がプロトタイプメソッドと一緒にコンストラクタを定義する構文糖と見なすことができる理由は確かにあります。それでも、重要な違いがあります。
-
まず、
class
によって作成された関数は、特別な内部プロパティ]:"classConstructor"
によってラベル付けされます。 したがって、手動で作成するのとまったく同じではありません。言語は、さまざまな場所でそのプロパティをチェックします。, たとえば、通常の関数とは異なり、
new
:class User { constructor() {}}alert(typeof User); // functionUser(); // Error: Class constructor User cannot be invoked without 'new'
また、ほとんどのJavaScriptエンジンにおけるクラスコンストラクタの文字列表現は”class…”
class User { constructor() {}}alert(User); // class User { ... }
他にも違いがありますが、すぐに見ることができます。
クラスメソッドは列挙可能ではありません。,クラス定義は、
enumerable
フラグをfalse
"prototype"
内のすべてのメソッドに対して"prototype"
に設定します。これは良いことです。
for..in
オブジェクトに対して、通常はそのクラスメソッドを必要としないためです。クラスは常に
use strict
。クラス構造内のすべてのコードは自動的にstrictモードになります。さらに、
class
構文には、後で説明する他の多くの機能があります。,クラス式
関数と同様に、クラスは別の式の中で定義したり、渡したり、返したり、割り当てたりすることができます。
クラス式の例は次のとおりです。
let User = class { sayHi() { alert("Hello"); }};
名前付き関数式と同様に、クラス式には名前が付いている場合があります。,
クラス式に名前がある場合、それはクラス内でのみ表示されます。
次のように、クラスを動的に”オンデマンド”にすることさえできます。
Getters/setters
リテラルオブジェクトと同じように、クラスにはgetter/setter、計算されたプロパティなどが含まれます。
以下は、
user.name
get/set
を使用して実装されたの例です。
技術的には、このようなクラス宣言は
User.prototype
にゲッターとセッターを作成することによって機能します。,計算された名前
角かっこを使用して計算されたメソッド名の例を次に示します
:
class User { () { alert("Hello"); }}new User().sayHi();
このような機能は、リテラルオブジェクトの
クラスフィールド
古いブラウザはポリフィルが必要な場合がありますクラスフィールドは、言語に最近追加されたものです。
以前は、クラスにはメソッドしかありませんでした。
“クラスフィールド”は、任意のプロパティを追加できる構文です。,
たとえば、
name
プロパティをclass User
:class User { name = "John"; sayHi() { alert(`Hello, ${this.name}!`); }}new User().sayHi(); // Hello, John!
だから、”=”と書くだけです。宣言では、それはそれです。,
クラスフィールドの重要な違いは、
User.prototype
:class User { name = "John";}let user = new User();alert(user.name); // Johnalert(User.prototype.name); // undefined
より複雑な式や関数呼び出しを使用して値を割り当てることもできます。
より複雑な式や関数呼び出しを使用して値を割り当てることもできます。
- 、それはクラス宣言の結果になります。 関数コードは、
class User { name = prompt("Name, please?", "John");}let user = new User();alert(user.name); // John
クラスフィールドでバインドされたメソッドを作成する
javascriptの関数バインド関数の章で示されているように、動的なthis
, それは呼び出しのコンテキストに依存します。
したがって、オブジェクトメソッドが渡され、別のコンテキストで呼び出された場合、this
はそのオブジェクトへの参照にはなりません。
たとえば、このコードはundefined
:
問題は”this
“を失うことと呼ばれます。P>
setTimeout(() => button.click(), 1000)
のようなラッパー関数を渡します。
のようなラッパー関数を渡します。
のようなラッパー関数を渡します。
のようなラッパー関数を渡します。
のような
click = () => {...}
はオブジェクトごとに作成され、各Button
オブジェクトごとに別々の関数があり、this
そのオブジェクトを参照 どこでもbutton.click
を渡すことができ、this
の値は常に正しいでしょう。
これは、イベントリスナーのために、ブラウザ環境で特に便利です。,
Summary
基本的なクラス構文は次のようになります。
MyClass
技術的には関数(constructor
として提供する関数)ですが、メソッド、ゲッター、セッターはMyClass.prototype
に書き込まれます。
次の章では、継承やその他の機能を含むクラスについてもっと学びます。