JavaScriptのOOP



この記事では、JavaScriptのオブジェクト指向プログラミングの主な機能について説明します。



JavaScriptオブジェクト


JavaScriptのオブジェクトは、キーと値のペアのセットを含む連想配列です(「ハッシュ」、「オブジェクト」、「連想配列」はJavaScriptでも同じことを意味します)。

JavaScriptでオブジェクトを作成する:

 var obj = new Object(); //    var obj = {}; //    . 

オブジェクトプロパティの設定:

 obj.name = 'Victor'; //  .property obj['name']='Victor'; //    

プロパティへのアクセス:

 console.log(obj.name); //  .property console.log(obj['name']); //        

拡張オプション:

 var obj = { name : 'Viktor', age : 32 }; 

コンストラクターとキーワードnew


コンストラクターは、コンストラクターとして使用される関数です 。」 ECMAScript 6より前は、JavaScriptにはコンストラクターの概念がありませんでした。 newキーワードを使用して呼び出される関数であればどれでもかまいません。

コンストラクターの使用例:

  var Donkey = function(){ //… }; //   «» var iaDonkey = new Donkey(); 

新しいドンキー()を呼び出すとき、JavaScriptは4つのことを行います。

  1. 1.新しいオブジェクトを作成します。
    iaDonkey = new Object(); // .
  2. 2. Donkeyオブジェクトのコンストラクタプロパティを配置します。
    aDonkey.constructor == Donkey // true
    iaDonkey instanceof Donkey // true
  3. 3. Donkey.prototypeに転送するオブジェクトを設定します。
    iaDonkey.__proto__ = Donkey.prototype
  4. 4.新しいオブジェクトのコンテキストでドンキー()を呼び出します。
      var iaDonkey = function(){ this.constructor(); // function Donkey() // … }; 

 //   ,    : function New (F, args) { /*1*/ var n = {'__proto__': F.prototype}; /*2*/ F.apply(n, args); /*3*/ return n; } 

  1. 新しい値(n)を作成し、 prototype値をproto書き込みます。
  2. applyを介してメソッドコンストラクターを呼び出しapply
  3. クラスNew新しいオブジェクトを返します。

短絡カプセル化


クロージャーは、関数を介して作成できるスコープベースのメカニズムです。 各関数は新しいスコープを作成します。

2つの例を見てみましょう。

例1:

  for (var i = 0; i < 10; i++) { setTimeout(function () { console.log(i); }, 0); } 

このループでは、ダースが10回表示されます。最後の繰り返しの後、10が表示され、 setTimeoutが開始されます。

例2:

  for (var i = 0; i < 10; i++) { (function (m) { setTimeout(function () { console.log(m); },0); })(i) } 

匿名の自己呼び出し関数を使用すると、宣言された直後に関数の実行を開始できます。

クロージャの原則を適用しました。関数を宣言し、実際の値を渡し、変数i. m値をそれ自体で「閉じます」 i. m i. mはクロージャを介して最も近い上位のスコープから値を取得しようとします。 そして、それを自己呼び出し関数に渡したため、毎回その値(変数iの値)に等しくなり、0から9を10回取得します。

クロージャーとカプセル化に関するこの例は、実際のプロジェクトから引用したものです。



BarChart関数があり、パブリックメソッドがあります-チャートを作成し、その値を更新します。 プライベートなメソッドとプロパティがあります-それを外の世界に見せないでやるべきことです。

newを介してBarChartにアクセスすると、これがコンストラクター関数であることがわかり、このクラスの新しいオブジェクトを作成します。 ただし、すべてのプライベートメソッドはこの変数でロックされており、内部でアクセスできます。 これらは、この関数が作成するスコープ内に残ります。

多態性および呼び出し/適用キーワード


apply構造のapply

 var obj = { outerWidth: 'pliers' }; function getWidth(){ return this.outerWidth; } var a = getWidth(); var b = getWidth.apply(obj); console.log(a); //   , this  windows console.log(b); //    pliers. outerWidth —    windows, ,  ,  windows.outerWidth 

メカニズム呼び出し:

 Calling func.call(context, a, b...) 

書くことと同等:

 func(a, b...), but this == context. 

両方の呼び出しは同一で、配列を介してパラメータを渡すことができるのは適用のみです。

 call(context, param1, param2 …) apply(context, [args]) 

4つの呼び出しオプションとその結果:

  function: function(args) – this == window  method: obj.funct(args) – this == obj Apply: func.apply(obj,args) – this == obj Constructor: new func(args) – this == new object 

継承および実装方法




基本フィルターモデルは、任意のアプリケーションのフィルター内にあるパラメーターの標準セットです。 これらのパラメーターは、ページネーション、ページ番号などに必要です。

彼にプロトタイプを通してメソッドを提供します。 サーバーモデルを受け取った後、このメソッドを呼び出し、データの一部を目的の形式に変換します。

後継クラスと特定の「RouteHistorical」ページがあります。 クラスはベースフィルターを継承しますが、さらに独自のフィールドとパラメーターを持っています。



73行目RouteHistoricalは、同じ引数RouteHistorical新しく作成されたRouteHistoricalオブジェクトRouteHistorical applyコンテキストを通じて基本クラスに渡します。 メソッドはすべてのフィールドを初期化し、新しいオブジェクトを取得します。

RouteHistoricalベースフィルターの継承者にすることができます。 81行目に、 prototypeプロパティにベースコンストラクタークラスへの参照を記述します。 prototypeメソッドは完全に上書きされ、コンストラクタは失われます。 新しいオブジェクトを作成するとき、何に向けるべきかわかりません。

82行目で、 prototype.constructorプロパティをそれ自体へのリンクに設定します。 constructorクラスのプロパティは常に自身を参照します。

プロトタイプ


prototypeプロパティは、 newキーワードと組み合わせたときに意味があります。 新しいオブジェクトを作成するとき、 prototype値を__proto__プロパティに書き込みます。 クラスの親であるクラスへの参照が含まれています。



prototype 、新しいオブジェクトをインスタンス化するときに__proto__に書き込む必要があるものを言うためにのみ必要です。

  // unsafe var filter = { EnablePagination: true }; function BaseFilter(size) { this.PageSize = size; this.__proto__ = filter; } // safe var filter= { EnablePagination: true }; function BaseFilter(size) { this.PageSize = size; } BaseFilter.prototype = filter; 

2つのエントリは同じですが、 __proto__直接アクセスすることは安全ではないと見なされ、すべてのブラウザがこれを許可するわけではありません。

基本クラスから子孫を作成する


extend機能:

  function extend(Child, Parent) { var F = function() { } F.prototype = Parent.prototype // Child.prototype = new F() //   Child  __proto__    prototype Child.prototype.constructor = Child //  ,     . Child.superclass = Parent.prototype //      Parent }; 

使用法:

  function BaseFilterModel(..) { ... } function RouteHistoricalFilterModel(..) { ... } 

instanceof


オブジェクトがプロトタイプチェーン全体に基づいて、コンストラクターのインスタンスであるかどうかを判断できます。

instanceof(擬似メソッドコード):

  function isInstanceOf(obj, constructor) { if (obj.__proto__ === constructor.prototype) { return true; } else if (obj.__proto__ !== null) { return isInstanceOf(obj.__proto__, constructor) } else { return false } }; 

まとめ


1. ECMAScript 6より前のJavaScriptでは、クラスはなく、 newキーワードを使用して呼び出されるコンストラクター関数のみがありました。
2.プロトタイピングチェーンは、JavaScript継承の基盤です。
3.プロパティにアクセスすると、オブジェクトで検索されます。 そうでない場合は、チェーン全体で__proto__などになります。 したがって、継承はJavaScriptで実装されます。
4. fn.__proto__へのリンクをfn.prototypeます。
5. new演算子は、 F.prototypeを参照するF.prototypeプロパティを持つ空のオブジェクトを作成します。 コンストラクターはF実行します。thisコンテキストは以前に作成されたオブジェクトであり、そのプロパティを設定してこのオブジェクトを返します。
6. instanceofオペレーターは、 ObjectsConstructorコンストラクターを介してオブジェクトが作成されたことを確認しませんが、プロトタイピングチェーン全体に基づいて決定を行います。
7. JavaScriptでは、 thisはコンテキストに依存します。つまり、 関数の呼び出し方法について。

Source: https://habr.com/ru/post/J302518/


All Articles