JavaScriptを---> [研究ノート]&感謝オブザーバーパターン&工場モデルオブジェクト&コンストラクタモード

説明

  • このシリーズ(JSベースカーディング)が準備中のTCP実装の背中をシミュレートします
  • Benpian主な要素:オブザーバーパターン、プラントモデル、およびオブジェクトのモデルコンストラクタ理解

1.オブザーバーパターン

1.1メッセージの登録方法

「加入者登録メッセージは、メッセージキュー内に押し込みます。」

[アルゴリズム思考]:

  1. メッセージキューに押し込まれたとき、メッセージが存在しない場合は、メッセージのタイプとメッセージキューにメッセージを作成する必要があります
  2. このメッセージが存在する場合、メッセージは、(スムーズに行うことができ、登録メッセージを確実にするために、複数のモジュール)は、メッセージ・キューに対応する方法を実行するための方法を実行するために押さなければなりません
regist: function(type, fn) {
  // 如果消息不存在则应该创建一个该消息类型
  if(typeof __message[type] === 'undefined') {
    // 将动作推入到该消息对应的动作执行队列中
    __message[type] = [fn];
  // 如果此消息存在
  } else {
    // 将动作方法推入该消息对应的动作执行序列中
    __message[type].push(fn);
  }
}

1.2ニュースリリース方法

「オブザーバーのすべての加入者へのメッセージは、メッセージを発行したときにニュースリリースの方法、およびその機能のために実行されます」

fire: function(type, args) {
  // 如果该消息没有被注册,则返回
  if(!__message[type])
    return;
  // 定义消息信息
  var events = {
    type: type,
    args: args || {}
  },
  i = 0,
  len = __message[type].length;
  // 遍历消息动作
  for(; i < len; i++) {
    // 依次执行注册的消息对应的动作序列
    __messages[type][i].call(this, events);
  }
}

1.3メッセージログアウト方法

「加入者は、メッセージキューからメッセージをクリアするためにキャンセルされます。」

remove: function(type, fn) {
  // 如果消息队列存在
  if(__messages[type] instanceof Array){
    // 从最后一个消息动作遍历
    var i = __message[type].length - 1;
    for(; i>= 0; i--) {
      // 如果存在该动作则在消息动作序列中移除相应动作
      __messages[type][i] === fn && __messages[type].splice(i, 1);
    }
  }
}

2.オブジェクト指向プログラミングオブジェクト

オブジェクト指向(オブジェクト指向、OO)言語は、それらが、クラスの概念を持っているというサインを有し、そしてクラスで同じプロパティとメソッドを有する複数のオブジェクトを作成することができます。ECMAScriptのは、クラスという概念がないので、それはまた別のオブジェクトとオブジェクト言語クラスです。

ECMA-262は、オブジェクトのように定義されている置く:「順不同属性、基準値、オブジェクトまたは機能を含むことができるプロパティのセット」厳密に言えば、これは、オブジェクトが値のセット順不同であると言うことと等価です。オブジェクトの各プロパティとメソッドは、名前を持ち、それぞれの名前を値にマッピングされます。このため、私たちは、ECMAScriptのオブジェクトのハッシュテーブルを想像することができます。何よりも値がデータまたは関数とすることができる名前と値のペアのセット、より

2.1オブジェクトを理解します

  • オブジェクトを作成する最も簡単な方法
  • オブジェクトのインスタンスを作成し、そこにプロパティとメソッドを追加します
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function() {
  alert(this.name);
};

初期のJavaScript開発者は、上記の方法を使用してオブジェクトを作成します。数年後、好ましい態様として、オブジェクトリテラルは、このようなオブジェクトを作成します。

var person = {
  name: "Nicholas",
  age: 29,
  job: "Software Engineer",

  sayName: function(){
    alert(this.name);
  }
};

2.1.1属性タイプ

のみだけ内部特徴(属性)によって定義されたECMA-262第5版は、種々の特性(プロパティ)を記述する。ECMA-262そうJavaScriptで、我々はそれらを直接アクセスすることはできません、JavaScriptエンジンを使用するためにこれらの特性を定義します。内部特性値を表示するためには、[列挙]例えば、本明細書中で子供角括弧の二対それらを置きます

  1. データ属性の
    位置値を含むデータ属性データ。あなたはこの位置に値を読み書きすることができます。その動作特性を記述した4つのデータの属性があります。

    • [構成可能]]は:削除[削除]属性は、再定義のプロパティを通じて、プロパティ、またはアクセス属性のプロパティを変更する機能の特性を変更することができるかどうかを示します。性質上、前の例では、オブジェクトに直接定義されたように、デフォルトは真です。
    • [Enumberable]:FOR-でを通して戻して再利用するかどうかを示す属性が、デフォルトは真です。
    • [書き込み可能]]:属性値を修正するために、デフォルトは真であるかどうかを示します。
    • [値]:プロパティのデータ値は、デフォルトでは未定義です

    そのオブジェクトのプロパティに直接上記栗前のように定義される[構成可能]]、[[Enumberable]]と[を[書き込み可能]プロパティがtrueに設定されているため、[[値]]特性を設定します指定された値。

var person = {
  name: "Nicholas"
}

デフォルトのプロパティのプロパティを変更するには、Object.definePropertyのECMAScript5()メソッドを使用する必要があります。オブジェクト属性が配置されている、および属性記述子オブジェクトの名前:このメソッドは、3つの引数を受け入れます。オブジェクトの属性記述子(記述子)がされなければならない:設定可能、列挙、書き込み可能な値。

var person = {};
Object.defineProperty(person,"name", {
  writable: false,
  value: "Nicholas"
});
  1. アクセスプロパティは、
    プロパティアクセサデータ値が含まれていない。彼らは子供のgetterとsetter関数のペアが含まれています。読み取りアクセスプロパティは、有効な値を返すために責任があるgetter関数、呼び出すと、アクセサプロパティセッター関数呼び出しを書いて、新しい値を渡すときに、この機能は、データをどのように処理するかを決定する責任があります。
  • [[Configurable]]:プロパティを再定義するために、プロパティを削除するには、Deleteているかどうかを示します。
  • [[Enumerable]]:のためのインを介してリサイクルバックするかどうかを示す属性。
  • [[Get]]:プロパティを読み込むときに呼び出される関数は、デフォルト値が定義されていません
  • [[Set]]:プロパティを書くときに呼び出される関数は、デフォルト値が定義されていません

プロパティを直接定義することはできないアクセサ、あなたがObject.defineProperty()が定義されているを使用する必要があります。

var book = {
  _year: 2004,
  edition: 1
};
Object.defineProperty(book, "year", {
  get: function() {
    return this._year;
  },
  set: function(newValue) {
    if(newValue > 2004){
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
});
book.year = 2005;
alert(book.edition);

2.1.2は、複数の属性を定義します

ECAMAScript5もObject.defineProperties()メソッドを定義しました。この方法を使用すると、複数の属性記述子を定義することができます

var book = {};
Object.defineProperties(book, {
  _year: {
    writable: true,
    value: 2004
  },
  edition: {
    writable: true,
    value: 1
  },
  year: {
    get: function() {
      return this._year;
    },
    set: function(newValue) {
      if(newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});

2.1.3読み取り属性特性

使用Object.getOwnPropertyDescriptor ECMAScript5()メソッドは、指定されたプロパティ記述子を達成することができます。オブジェクト属性と属性名、その記述子が読み込まれる:この方法では、2つのパラメータを取ります。それはアクセス属性、オブジェクトおよび設定可能の属性、列挙、取得および設定されている場合、戻り値は、オブジェクトであり、データ属性、オブジェクトの属性や設定可能な、列挙、書き込み可能な値ならば。

var book = {};
Object.defineProperties(book, {
  _year: {
    value: 2004
  },
  edition: {
    value: 1
  },
  year: {
    get: function(){
      return this._year;
    },
    set: function(newValue){
      if (newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value);    // 2004
alert(descriptor.configurable);   // false
alert(typeof descriptor.get);   // "undefined"

var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value);
alert(descriptor.enumerable);
alert(typeof descriptor.get);

2.2ファクトリパターン

  • オブジェクトリテラル短所:使用多くのオブジェクトを作成するための単一のインターフェイスを、それが重複したコードの多くを生成します。
  • 抽象特定のオブジェクトを作成するプロセス
  • ECMAScriptのクラスを作成することはできません考えると、開発者は次の関数を発明しました。
function createPerson(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function(){
    alert(this.name);
  };
  return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
  • 工場パターン欠点:物体認識は、(上述のcreatePersonクラスとして検出することができるように)オブジェクトのタイプを知ることが、すなわち、どのように問題を解決しません。

2.3モデルのコンストラクタ

  • ECMAScriptのコンストラクタは、オブジェクトの特定の型を作成するために使用することができます。
function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  };
}
var person1 = new Person("Nicholas", 29, "Softwate Engineer");
var person2 = new Person("Greg", 27, "Doctor");

2.3.1差異工場モデルコンストラクタと

  • オブジェクトを作成するためには表示されません。
  • 直接このオブジェクトのプロパティとメソッドに割り当てられました
  • いいえreturn文ません

2.3.2新しいコンストラクタ

  • 新しい演算子を使用して、コンストラクタは、実際に以下の4つのステップを受ける呼び出し:
    (1)新しいオブジェクトを作成する;
    (2)コンストラクタの範囲は新しいオブジェクト(新規オブジェクトにこの点)を割り当て、
    (3新しいオブジェクトの属性に追加)コンストラクタポイントコード();
    (4)新しいオブジェクトを返します

[栗]:

  1. PERSON1は人のインスタンスを検出していません
console.log(person1 instanceof Person);

将来的には、特定の型のインスタンスとして同定することができるカスタムコンストラクタ手段を作成します。

2.3.3は、new演算子の呼び出しコンストラクタを使用しません

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  }
}
Person("Greg", 27, "Doctor");
alert(Window.name);     // "Greg"
  • これらのプロパティとメソッドは、グローバルオブジェクトにマウントする必要があります。

2.3.4問題のコンストラクタ

  • 「すべてのメソッドは、各インスタンスに再び再作成する必要があります。」:主な問題は、コンストラクタということです
// 前面的构造函数等价于
function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = new Function("alert(this.name)");
}
  • 以上の観点から、各Personインスタンスは、異なる関数の例を含んでいます
  • 具体的にはコンストラクタ関数を作成するために、言えば、それは別のスコープチェーンと識別子の解決につながります
  • 次のコードの証明機能が異なっています。
console.log(person1.sayName === person2.sayName);   //false

3.まとめ

3.1ファクトリパターン

  • 抽象オブジェクトの作成
  • 欠点は:オブジェクトは、工場のパターンを使用して作成された特定のクラスとして認識されません

3.2コンストラクタモード

  • 問題のクラスを解決するために、工場出荷時のパターン認識。

  • 短所は以下のとおりです。同じメソッドの異なるインスタンス間でリソースの異なる廃棄物です。

  • ソリューション:プロトタイプモデル

公開された177元の記事 ウォン称賛22 ビュー20000 +

おすすめ

転載: blog.csdn.net/piano9425/article/details/103926466