この記事は ES6 クラスと継承の実装原則 (コード例) に関するもので、必要な方は参考にしていただければ幸いです。
1. es6 クラスは
Javascript はプロトタイプの継承を使用します。
es6 は、プロトタイプの性質を利用してクラスの継承を実現します。砂糖のようなオブジェクト指向継承。
class Parent { constructor(a){ this.filed1 = a; } filed2 = 2; func1 = function(){} } class Child extends Parent { constructor(a,b) { super(a); this.filed3 = b; } filed4 = 1; func2 = function(){} }
babel を使用して、es6 クラスと継承の実装原則を調べてみましょう。
1. クラスの実装
変換前:
class Parent { constructor(a){ this.filed1 = a; } filed2 = 2; func1 = function(){} }
変換後:
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Parent = function Parent(a) { _classCallCheck(this, Parent); this.filed2 = 2; this.func1 = function () { }; this.filed1 = a; };
クラスの最下層は依然としてコンストラクターであることがわかります。 :
1. _classCallCheck メソッドを呼び出して、現在の関数呼び出しの前に新しいキーワードがあるかどうかを確認します。
コンストラクターが実行される前に new キーワードが使用されると、コンストラクター内に空のオブジェクトが作成され、コンストラクターの proptype は空のオブジェクトの _proto_ を指し、this は空のオブジェクトの _proto_ を指します。空のオブジェクトに。上記と同様に、_classCallCheck: このインスタンスの Parent は true を返します。
コンストラクターの前に new がない場合、コンストラクターの proptype は this のプロトタイプ チェーンに表示されず、 false が返されます。
2. クラス内の変数と関数をこのに代入します。
3. コンストラクターの内部ロジックを実行します。
4.これを返します (デフォルトでは、コンストラクターは最後に実行されます)。
変換前:
class Child extends Parent { constructor(a,b) { super(a); this.filed3 = b; } filed4 = 1; func2 = function(){} }
変換後:
まず Child の内部実装を見てみましょう。内部呼び出しを見てください。 関数の実装方法:
var Child = function (_Parent) { _inherits(Child, _Parent); function Child(a, b) { _classCallCheck(this, Child); var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, a)); _this.filed4 = 1; _this.func2 = function () {}; _this.filed3 = b; return _this; } return Child; }(Parent);
1. _inherits 関数を呼び出して、親クラスの proptype を継承します。
_内部実装を継承:
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
(1) 親コンストラクターを確認します。
(2) 典型的な寄生継承: 親クラス コンストラクターの proptype を使用して空のオブジェクトを作成し、このオブジェクトがサブクラス コンストラクターの proptype を指すようにします。
(3) 親コンストラクターが子コンストラクターの _proto_ を指すようにします (このステップが何をするのかは不明であり、意味がないと思われます。)
2 クロージャーを使用します。パッケージは親クラスの参照を保存し、クロージャ内でサブクラス構築ロジックを実行します。
3.新しいチェック。
4. 現在の this を使用して、親クラスのコンストラクターを呼び出します。
var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, a));
Child.__proto__ || Object.getPrototypeOf(Child) は実際には親コンストラクター (_inherits の最後の操作) であり、呼び出し元を現在の this through 呼び出しに変更してパラメーターを渡します。 (ここでは引数として渡したParentを直接使えそうな気がします)
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
これが初期化されているか、superが呼ばれているかを確認し、親クラスから割り当てられたthisを返します。
5. 行サブクラス内の変数と関数をこれに代入します。
6. サブクラス コンストラクター内のロジックを実行します。
es6 が実際に「結合寄生継承」を記述する簡単な方法を提供していることがわかります。
super は親クラスのコンストラクターを表します。
super.fun1() は、Parent.fun1() または Parent.prototype.fun1() と同等です。
super() は Parent.prototype.construtor() と同等です。
サブクラス コンストラクターを記述しない場合:
var Child = function (_Parent) { _inherits(Child, _Parent); function Child() { _classCallCheck(this, Child); return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments)); } return Child; }(Parent);
デフォルトのコンストラクターが親クラスのコンストラクターがアクティブに呼び出され、デフォルトでは、現在のコンストラクターによって渡されたパラメーターが親クラスに渡されます。
したがって、コンストラクターを宣言するときは、super() を積極的に呼び出す必要があります。そうしないと、親コンストラクターを呼び出すことができず、継承を完了できません。
典型的な例は Reatc のコンポーネントにあります。親クラスはコンストラクター内の props に対していくつかの初期化操作を行う必要があるため、コンストラクターを宣言した後に super(props) を呼び出す必要があります。
以上がES6クラスと継承の実装原則(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。