1

関数継承の問題は、多くのインスタンスを作成したい場合、関数を毎回宣言する必要があるため、処理が遅くなることです。

プロトタイプ継承の問題は、真にプライベート変数を持つ方法がないことです。

この 2 つを組み合わせて、両方の長所を活かすことは可能でしょうか? プロトタイプとシングルトンパターンの両方を組み合わせた私の試みは次のとおりです。

var Animal = (function () {
  var secret = "My Secret";

  var _Animal = function (type) {
    this.type = type;
  }
  _Animal.prototype = {
    some_property: 123,
    getSecret: function () {
      return secret;
    }
  };

  return _Animal;
}());

var cat = new Animal("cat");

cat.some_property; // 123
cat.type; // "cat"
cat.getSecret(); // "My Secret"

このパターンを使用することの欠点はありますか? 安全?効率?すでに存在する同様のパターンはありますか?

4

2 に答える 2

2

あなたのパターンはまったく問題ありません。

ここで、覚えておいていただきたいことがいくつかあります。
主に、最も外側のクロージャーで作成された関数と変数は、他の言語のプライベートな静的メソッド/メンバーのように動作します (構文的に実際に呼び出される方法を除く)。

プロトタイプ パラダイムを使用する場合、private-static メソッド/メンバーを作成することはもちろん不可能です。
外側のスコープに戻す前に、内側のコンストラクターにそれらを追加することで、public-static メンバー/メソッドをさらに作成できます。

var Class = (function () {
    var private_static = function () {},
        public_static  = function () {},

        Class = function () {
            var private_method = function () { private_static(); };
            this.method = function () { private_method(); }; 
         };

    Class.static = public_static;
    return Class;
}());

Class.static(); // calls `public_static`
var instance = new Class();
instance.method();
// calls instance's `private_method()`, which in turn calls the shared `private_static();`

このように「静的」関数を使用する場合、それらはインスタンスの内部状態にまったくアクセスできないことに注意してください。したがって、それらを使用する場合は、それらに何かを渡す必要があります。それらは必要であり、return ステートメントを収集する (または内部からオブジェクトのプロパティ/配列要素を変更する) 必要があります。

public_staticまた、上記のコードが与えられた任意のインスタンスの内部からClass.static();、パブリック関数を呼び出す完全に有効な方法です。これは、実際には静的ではなく、プロパティとして追加されているクロージャー内の単なる関数であるためです。インスタンスのスコープチェーン内にもある別のオブジェクトの。

追加のボーナスとして:
悪意のあるコード DID が public static メソッド ( Class.static) を攻撃して内部をハイジャックしようとしても、Class.staticプロパティへの変更は囲まれたpublic_static関数に影響しないため、内部バージョンを呼び出すことで、インスタンスは引き続きハッキングされます。 -人々をプライベートなものから遠ざける限り安全です...
別のモジュールがインスタンスに依存していて、そのインスタンスのパブリックメソッドが改ざんされていて、他のモジュールが与えられたすべてを信頼した場合... ...まあ、そのモジュールの作成者には残念ですが、少なくともあなたのものは安全です.

クロージャー以上のものを使用して、他の言語の機能を複製する万歳。

于 2013-03-26T00:56:35.847 に答える
1

機能継承とプロトタイプ継承を混ぜ合わせて、両方の長所を活かすことは可能でしょうか?

はい。そして、あなたはそれをするべきですthatとして初期化する代わりに、すべての非特権メソッドが配置されているプロト オブジェクトから継承するために{}使用します。ただし、そのような「クラス」からの継承は簡単ではなく、ファクトリを使用している場合でも、疑似古典的なアプローチObject.createのように見えるコードになってしまいます。

プロトタイプとシングルトン パターンの両方を組み合わせた私の試み。すでに存在する同様のパターンはありますか?

わかりましたが、それは上記とは何か違いますか? 実は、これはモジュールパターンとプロトタイプパターンを組み合わせた「Revealing Prototype Pattern」として知られています。

このパターンを使用することの欠点はありますか?

大丈夫です。あなたの例だけでは少し不必要です。あなたsecretは一種の静的変数であるため、インスタンスメソッドからアクセスするのはあまり意味がありません。短い:

function Animal(type) {
    this.type = type;
}
Animal.prototype.some_property = 123;
Animal.getSecret = function() {
    return "My Secret";
};
于 2013-03-26T01:13:24.800 に答える