ホームページ  >  記事  >  ウェブフロントエンド  >  JSオブジェクト指向基本解説(ファクトリーモード、コンストラクターモード、プロトタイプモード、ミックスモード、ダイナミックプロトタイプモード)_JavaScriptスキル

JSオブジェクト指向基本解説(ファクトリーモード、コンストラクターモード、プロトタイプモード、ミックスモード、ダイナミックプロトタイプモード)_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 16:39:341063ブラウズ

オブジェクト指向とは何ですか?オブジェクト指向は思想です! (ナンセンス)。

オブジェクト指向では、プログラム内の主要なモジュールをオブジェクトとみなすことができ、モジュールにはプロパティとメソッドがあります。このように、いくつかのプロパティとメソッドをカプセル化すると、将来使用するのに非常に便利になり、退屈で繰り返しの作業を避けることもできます。次にJSによるオブジェクト指向の実装について説明します。

工場出荷時モード

ファクトリ パターンは、ソフトウェア エンジニアリングの分野でよく知られた設計パターンです。ECMAScript ではクラスを作成できないため、関数のカプセル化を使用して特定のインターフェイスを持つオブジェクトを作成します。実装方法は非常に簡単で、関数内でオブジェクトを作成し、そのオブジェクトにプロパティやメソッドを代入し、そのオブジェクトを返すだけです。

function createBlog(name, url) {
  var o = new Object();
  o.name = name;
  o.url = url;
  o.sayUrl= function() {
    alert(this.url);
  }
  return o;
}

var blog1 = createBlog('wuyuchang', 'http://www.jb51.net/');

ファクトリ パターンの実装方法は非常に簡単で、類似したオブジェクトを複数作成する問題は解決されていることがわかります。ただし、ファクトリ パターンは、Date、Array、Date、Array とは異なり、すべてオブジェクトであるため、オブジェクトの種類を識別できません。など、Constructor パターンがあります。

コンストラクターパターン

ECMAScript のコンストラクターは、Array や Date などのネイティブ JS オブジェクトと同様に、特定の型のオブジェクトを作成できます。実装方法は以下の通りです:

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = function() {
    alert(this.url);
  }
}

var blog = new Blog('wuyuchang', 'http://www.jb51.net/');
console.log(blog instanceof Blog);  // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能

この例と工場出荷時のモデルの関数名の違いを除けば、注意深いお子様であれば多くの違いに気づくはずです。

関数名の最初の文字は大文字にする必要があります (標準では最初の文字を大文字にすることは厳密に要求されていませんが、慣例により、コンストラクターの最初の文字は大文字にする必要があります
作成されたオブジェクトは表示されません
このオブジェクトにプロパティとメソッドを直接割り当てます
return ステートメントはありません
new を使用してオブジェクトを作成します
オブジェクトを認識できる (この点で、コンストラクター パターンがファクトリー パターンよりも優れています)

コンストラクターは使いやすいですが、欠点がないわけではありません。コンストラクターを使用する場合の最大の問題は、インスタンスが作成されるたびにメソッドを再作成する必要があることです (理論上、オブジェクトのプロパティは次のようになります)。オブジェクトのメソッドは同じですが、まったく同じメソッドを 2 回作成する必要はないので、関数をオブジェクトの外に移動することができます (おそらく、一部の子供たちはすでに欠点に気づいていますが、ブー!)。

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = alertUrl;
}

function alertUrl() {
  alert(this.url);
}

var blog = new Blog('scjb51', 'http://sc.jb51.net/'),
  blog2 = new Blog('jb51', 'http://www.jb51.net/');
blog.alertUrl();  // http://sc.jb51.net/
blog2.alertUrl();  // http://www.jb51.net/

blog と blog2 が同じ関数にアクセスできるように、alertUrl をグローバル関数として設定します。しかし、問題は、実際には Blog でのみ使用される関数を定義することになります。その名前にふさわしいものですが、さらに受け入れがたいのは、多くのメソッドが特定のオブジェクトによってのみ使用されるグローバル スコープで定義されていることです。スペースを無駄にすることは言うまでもなく、明らかにオブジェクト指向のカプセル化が失われるため、これはプロトタイプによって解決できます。 。 質問。

プロトタイプモード

作成するすべての関数には、オブジェクトへのポインターであるプロトタイプ属性があり、このオブジェクトの目的は、特定の型のすべてのインスタンスで共有できるプロパティとメソッドを含めることです。プロトタイプ オブジェクトを使用する利点は、すべてのオブジェクト インスタンスがそれに含まれるプロパティとメソッドを共有できることです。

function Blog() {
}

Blog.prototype.name = 'wuyuchang';
Blog.prototype.url = 'http://tools.jb51.net/';
Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];
Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend );
}

// 以下为测试代码
var blog = new Blog(),
  blog2 = new Blog();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4
blog2.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4

blog.name = 'wyc1';
blog.url = 'http://***.com';
blog.friend.pop();
blog2.name = 'wyc2';
blog2.url = 'http://+++.com';
blog.alertInfo();  // wyc1http://***.comfr1,fr2,fr3
blog2.alertInfo();  // wyc2http://+++.comfr1,fr2,fr3

プロトタイプ パターンには欠点がないわけではありません。まず、初期化パラメータを渡すためのコンストラクターが省略されているため、デフォルトではすべてのインスタンスが同じ属性値を取得します。これはまだプロトタイプではありません。プロトタイプ パターンの最大の問題は、共有の性質によって発生します。一方のインスタンスが参照を変更すると、もう一方のインスタンスも参照を変更します。したがって、通常はプロトタイプを単独で使用するのではなく、プロトタイプ パターンとコンストラクター パターンを組み合わせます。

混合モード(プロトタイプモード、コンストラクターモード)

function Blog(name, url, friend) {
  this.name = name;
  this.url = url;
  this.friend = friend;
}

Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend);
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']),
  blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);

blog.friend.pop();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2
blog2.alertInfo();  // wychttp://**.coma,b

混合モードでは、コンストラクター モードはインスタンス プロパティの定義に使用され、プロトタイプ モードはメソッドと共有プロパティの定義に使用されます。各インスタンスは独自のインスタンス属性を持ちますが、同時にメソッドを共有し、メモリを最大限に節約します。さらに、このモードは初期パラメータの受け渡しもサポートしています。利点はたくさんあります。このモードは、ECMAScript でカスタム オブジェクトを作成する方法として最も広く使用され、認識されています。

ダイナミックプロトタイプモード

動的プロトタイプモードは、コンストラクター内にすべての情報をカプセル化し、コンストラクター内でプロトタイプを初期化することで(最初のオブジェクトのインスタンス化時にプロトタイプのみ初期化されます)、メソッドが有効。 。

function Blog(name, url) {
  this.name = name;
  this.url = url;

  if (typeof this.alertInfo != 'function') {
    // 这段代码只执行了一次
    alert('exe time');
    Blog.prototype.alertInfo = function() {
      alert(thia.name + this.url);
    }
  }
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net'),
  blog2 = new Blog('wyc', 'http:***.com');

上記の例では、ウィンドウが「実行時」に一度だけポップアップすることがわかります。これにより、blog2 はプロトタイプを初期化する必要がなくなりました。このモードを使用してオブジェクトを作成します。

このブログ投稿は、「JavaScript による高度なプログラミング 」の第 3 版を参照していますが、言語が簡略化され、例が書き直されています。理解できない点がある場合は、そのままにしておいてください。返信があれば著者がブログを更新します。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。