このパターンは、Google Closure Libraryなどのフレームワークで使用されます。 ネイティブJavaScriptオブジェクトもこのパターンを使用します。
擬似クラス宣言
JavaScriptにはC、Java、PHPなどのような他の言語のようなクラスがないため、擬似クラスという用語が選択されましたが、このパターンはクラス定義に近いものです。
擬似クラスは、コンストラクター関数とメソッドで構成されます。
たとえば、
Animal
      
      擬似クラスは、1つの
sit
      
      メソッドと2つのプロパティで構成されます。
 function Animal(name) { this.name = name } Animal.prototype = { canWalk: true, sit: function() { this.canWalk = false alert(this.name + ' sits down.') } } var animal = new Animal('Pet') // (1) alert(animal.canWalk) // true animal.sit() // (2) alert(animal.canWalk) // false
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      -   
new Animal(name)
が呼び出されると、オブジェクトはAnimal.prototype
へのAnimal.prototype
リンクをAnimal.prototype
(図の右側を参照)。 -   
animal.sit
メソッドは、インスタンス内のanimal.canWalk
を変更するので、他の人ができるのに対して、私たちの動物はもはや歩くことができません。 
      擬似クラススキーマ:
- デフォルトのメソッドとプロパティはプロトタイプで定義されています。
 -   
prototype
メソッドはthis
使用します。thisの値は呼び出しのコンテキストに依存するため、現在のオブジェクトを指します。 したがって、animal.sit()
では、this
はanimal
指します。 
継承
Animal
      
      から継承する新しいクラス、たとえば
Rabbit
      
      作成しましょう。
 function Rabbit(name) { this.name = name } Rabbit.prototype.jump = function() { this.canWalk = true alert(this.name + ' jumps!') } var rabbit = new Rabbit('John')
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ご覧のとおり、ウサギは
Animal
      
      と同じ構造をしています-メソッドはプロトタイプで定義されています。
Animal
      
      から継承するには、
Rabbit.prototype.__proto__ == Animal.prototype
      
      を継承する必要があります。 メソッドが
Rabbit.prototype
      
      で見つからない場合、親
Animal.prototype
      
      メソッドで検索するため、これは自然な要件
Animal.prototype
      
      。
このように、例えば:
      これを実装するには、まず
Rabbit.prototype
      
      から継承した空の
Rabbit.prototype
      
      オブジェクトを作成してから、メソッドを追加する必要があります。
 function Rabbit(name) { this.name = name } Rabbit.prototype = inherit(Animal.prototype) Rabbit.prototype.jump = function() { ... }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      inherit
      
      は、指定された
__proto__
      
      空のオブジェクトを作成します。
 function inherit(proto) { function F() {} F.prototype = proto return new F }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      最後に起こったことは次のとおりです。
 // Animal function Animal(name) { this.name = name } // Animal methods Animal.prototype = { canWalk: true, sit: function() { this.canWalk = false alert(this.name + ' sits down.') } } // Rabbit function Rabbit(name) { this.name = name } // inherit Rabbit.prototype = inherit(Animal.prototype) // Rabbit methods Rabbit.prototype.jump = function() { this.canWalk = true alert(this.name + ' jumps!') } // Usage var rabbit = new Rabbit('Sniffer') rabbit.sit() // Sniffer sits. rabbit.jump() // Sniffer jumps!
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
       継承にnew Animal
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用しないでください 
      Rabbit.prototype = inherit(Animal.prototype)
      
      代わりに次のことを行うのは、よく知られていますが、正しい継承方法ではありません。
 // inherit from Animal Rabbit.prototype = new Animal()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      その結果、プロトタイプに
new Animal
      
      が
new Animal
      
      れます。
new Animal
      
      Animal.prototype
      
      自然に継承するため、継承は
Animal.prototype
      
      ます。
...しかし、
new Animal()
      
      は
name
      
      なしで呼び出すことができると言ったのは誰ですか? コンストラクターは厳密に引数を必要とし、引数なしで死ぬことができます。
実際、問題はこれよりも概念的です。
Animal
      
      は作成しません。 私たちは彼から継承したいだけです。
これが、
Rabbit.prototype = inherit(Animal.prototype)
      
      が望ましい理由
Rabbit.prototype = inherit(Animal.prototype)
      
      。 副作用のないきちんとした継承。
スーパークラスコンストラクターコール
スーパークラスコンストラクターが自動的に呼び出されるようになりました。 現在のオブジェクトに対して
Animal.apply()
      
      を使用して、ハンドルで呼び出すことができます。
 function Rabbit(name) { Animal.apply(this, arguments) }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      このコードは、現在のオブジェクトのコンテキストで
Animal
      
      コンストラクターを実行し
name
      
      インスタンスの
name
      
      設定
name
      
      ます。
メソッドの再定義(多態性)
親メソッドをオーバーライドするには、子プロトタイプで置き換えます:
 Rabbit.prototype.sit = function() { alert(this.name + ' sits in a rabbity way.') }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      rabbit.sit()
      
      が呼び出されると、
sit
      
      はチェーン
rabbit -> Rabbit.prototype -> Animal.prototype
      
      によって検索され、
Rabbit.prototype
      
      に到達する前に
Animal.prototype
      
      ます。
もちろん、オブジェクト内で直接、別の方法で再定義できます。
 rabbit.sit = function() { alert('A special sit of this very rabbit ' + this.name) }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      オーバーライド後に親メソッドを呼び出す
メソッドをオーバーライドした後でも、親メソッドを呼び出す必要がある場合があります。 これは、親プロトタイプを直接使用する場合に可能です。
 Rabbit.prototype.sit = function() { alert('calling superclass sit:') Animal.prototype.sit.apply(this, arguments) }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      すべての親メソッドは、現在のオブジェクトが
this
      
      として渡される
apply/call
      
      で呼び出され
apply/call
      
      。
Animal.prototype.sit()
      
      への単純な呼び出しは、
this
      
      として
Animal.prototype
      
      を使用し
this
      
      。
砂糖:親への直接参照の削除
前の例では、親クラスを直接呼び出しました。 コンストラクターとして:
Animal.apply...
      
      、またはメソッド:
Animal.prototype.sit.apply...
      
      実際、これを行うべきではありません。 屈折処理中に、名前を変更したり、階層の中間クラスを追加したりできます。
通常、プログラミング言語では、
parent.method()
      
      や
super()
      
      などの特別なキーワードを使用して親メソッドを呼び出すことができます。
しかし、これはJavaScriptの場合ではありませんが、モデル化できます。
次の関数は継承を拡張し、直接参照せずに親とコンストラクタを設定します。
 function extend(Child, Parent) { Child.prototype = inherit(Parent.prototype) Child.prototype.constructor = Child Child.parent = Parent.prototype }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      だからここで使用できます:
 function Rabbit(name) { Rabbit.parent.constructor.apply(this, arguments) // super constructor } extend(Rabbit, Animal) Rabbit.prototype.run = function() { Rabbit.parent.run.apply(this, arguments) // parent method alert("fast") }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      その結果、
Animal
      
      名前を変更したり、中間の
GrassEatingAnimal
      
      クラスを作成したりできます
GrassEatingAnimal
      
      と
extend(...)
      
      のみが影響を受けます。
プライベートで安全な方法(カプセル化)
保護されたメソッドとプロパティは、命名規則によってサポートされています。 アンダースコア「_」で始まるメソッドは、外部から呼び出すべきではありません(実際には可能です)。
      プライベートメソッドはサポートされていません。
静的メソッドとプロパティ
静的メソッドとプロパティはコンストラクターで定義されます:
 function Animal() { Animal.count++ } Animal.count = 0 new Animal() new Animal() alert(Animal.count) // 2
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      合計
スーパーメガOOPフレームワークは次のとおりです。
 function extend(Child, Parent) { Child.prototype = inherit(Parent.prototype) Child.prototype.constructor = Child Child.parent = Parent.prototype } function inherit(proto) { function F() {} F.prototype = proto return new F }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      使用法:
 // --------- the base object ------------ function Animal(name) { this.name = name } // methods Animal.prototype.run = function() { alert(this + " is running!") } Animal.prototype.toString = function() { return this.name } // --------- the child object ----------- function Rabbit(name) { Rabbit.parent.constructor.apply(this, arguments) } // inherit extend(Rabbit, Animal) // override Rabbit.prototype.run = function() { Rabbit.parent.run.apply(this) alert(this + " bounces high into the sky!") } var rabbit = new Rabbit('Jumper') rabbit.run()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      たとえば、あるオブジェクトから別のオブジェクトにプロパティをコピーする関数など、少しだけ砂糖をフレームワークに追加できます。
 mixin(Animal.prototype, { run: ..., toString: ...})
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ただし、実際には、このOOPパターンを使用する必要はありません。 これを処理できるのは2つの関数のみです。