2015-01-10 7 views
7

私はビデオを今度はthis question on class-free OOPから数回見ましたが、これを現実世界の例に適用するのは問題です。Crockfordの新しいコンストラクタパターンで "コンストラクタ"機能をどのように共有できますか?

クロックフォードの新しいコンストラクタパターンは次のようになります。specはオプションのハッシュし、その結果のオブジェクトをある

function constructor(spec) { 
    let {member} = spec, 
     {other} = other_constructor(spec), 
     method = function() { 
     // accesses member, other, method, spec 
     }; 

    return Object.freeze({ 
     method, 
     other, 
    }); 
} 

は、内部のメンバーのすべてを超える閉じるメソッドを公開します。この構造を無視してください(これは現在のJSで長い形式で行うことができます)このパターンを実際の例でどのように適用するのですか?

現在、基本クラスModule(model, id)のライブラリがあります。modelは、ブートストラップデータです。

// constructor, original flavor 
function Module(model, id) { 
    this.id = id; 
    this.model = model; 
} 

私は、この親Moduleから継承したモジュールのいくつかの味を持っています。

// constructor, Crockford's Cool Ranch 
function module(spec) { 
    let id = spec.id, 
     model = spec.model; 

    return Object.freeze({}); 
} 

私は(すべてで継承を使用しているように見えるのではなく、複数のソースからオブジェクトを構成しない)クロックフォードのパターンを使用しない方法:クロックフォードのパターンの下で、私の代わりに、「コンストラクタ」としてこれを持っているでしょうは、複数のフレーバーのモジュールの間でこの基本的な構成を共有します

私はidmodelが各モジュールの "コンストラクタ"のローカル変数になることを知っています。私は本質的に、Crockfordのパターンを使用してモジュールの各フレーバに対して繰り返すことを避ける方法を尋ねています。

+0

私はまた、この他の質問で、私が理解していない答えを信じていることを最初に指摘したいと思います。 : – Mathletics

+0

あなたはここに隠喩を混在させています; 3番目のボックスは2番目のボックスと似ていません。3番目はprotoなしの空白のオブジェクトを返します。2番目のオブジェクトはprotoと2個のカスタムオブジェクトを返します。 crockfordは、プロトタイプのシンプルさを持っています(その場合、_prototype_ではなく_other_から一度に複数のメソッドを取得するのと同じですが)extend()を使用してすべてを反復することなく、ツール。 – dandavis

+0

@dandavis私は2番目のボックスにプロパティが公開されていることを知っています.3番目はプライベートです。2番目のボックスを完全に無視すると、答えは同じですか?必要なセットアップコードを繰り返さないようにする方法はありませんモジュールの各フレーバーにプライベートメンバーを割り当てますか? – Mathletics

答えて

8

クロフトフォードが“クラスフリーの継承を呼び出すものは、実際にはまだプロトタイプの継承です。委任(別名差分継承)を介して

  1. 原型継承:実際には、原型継承メカニズムのtwotypesがあります。
  2. クローニングによるプロトタイプ継承(a.k.a.連結継承)。

差動原型継承の例

これは私が伝統的にオブジェクト指向のJavaScriptコードを記述する方法である:

var Aircraft = defclass({ 
 
    constructor: function (model, speed) { 
 
     this.model = model; 
 
     this.speed = speed; 
 
    }, 
 
    describeAircraft: function() { 
 
     alert("The " + this.model + " flies at " + this.speed + " speed."); 
 
    } 
 
}); 
 

 
var FighterAircraft = extend(Aircraft, { 
 
    constructor: function (model, speed, radar) { 
 
     Aircraft.call(this, model, speed); 
 
     this.radar = radar; 
 
    }, 
 
    describeFighterAircraft: function() { 
 
     this.describeAircraft(); 
 
     alert("It has a " + this.radar + " radar signature."); 
 
    } 
 
}); 
 

 
var superFlanker = new FighterAircraft("Super Flanker", "Mach 2.25", "low"); 
 

 
superFlanker.describeFighterAircraft();
<script> 
 
function defclass(prototype) { 
 
    var constructor = prototype.constructor; 
 
    constructor.prototype = prototype; 
 
    return constructor; 
 
} 
 

 
function extend(constructor, properties) { 
 
    var prototype = Object.create(constructor.prototype); 
 
    for (var name in properties) prototype[name] = properties[name]; 
 
    return defclass(prototype); 
 
} 
 
</script>

連結的原型継承

の例

これはCrockfordオブジェクト指向のJavaScriptコードを書くための擁護者:

var superFlanker = FighterAircraft({ 
 
    model: "Super Flanker", 
 
    speed: "Mach 2.25", 
 
    radar: "low" 
 
}); 
 

 
superFlanker.describeFighterAircraft();
<script> 
 
function Aircraft(spec) { 
 
    var model = spec.model; 
 
    var speed = spec.speed; 
 

 
    function describeAircraft() { 
 
     alert("The " + model + " flies at " + speed + " speed."); 
 
    } 
 

 
    return Object.freeze({ 
 
     model: model, 
 
     speed: speed, 
 
     describeAircraft: describeAircraft 
 
    }); 
 
} 
 

 
function FighterAircraft(spec) { 
 
    var aircraft = Aircraft(spec); 
 
    var model = spec.model; 
 
    var speed = spec.speed; 
 
    var radar = spec.radar; 
 

 
    function describeFighterAircraft() { 
 
     aircraft.describeAircraft(); 
 
     alert("It has a " + radar + " radar signature."); 
 
    } 
 

 
    return Object.freeze({ 
 
     model: model, 
 
     speed: speed, 
 
     radar: radar, 
 
     describeFighterAircraft: describeFighterAircraft 
 
    }); 
 
} 
 
</script>

ベター・連結的原型継承使用してミックスインは、波形接続型原型継承の

クロックフォードの方法は、繰り返しをたくさん持っています。代替は次のとおりです。

var aircraft = mixin({ 
 
    describeAircraft: function() { 
 
     alert("The " + this.model + " flies at " + this.speed + " speed."); 
 
    } 
 
}); 
 

 
var fighterAircraft = mixin(aircraft, { 
 
    describeFighterAircraft: function() { 
 
     this.describeAircraft(); 
 
     alert("It has a " + this.radar + " radar signature."); 
 
    } 
 
}); 
 

 
var superFlanker = fighterAircraft({ 
 
    model: "Super Flanker", 
 
    speed: "Mach 2.25", 
 
    radar: "low" 
 
}); 
 

 
superFlanker.describeFighterAircraft();
<script> 
 
function mixin() { 
 
    var length = arguments.length; 
 
    var index = 0; 
 

 
    while (index < length) { 
 
     var properties = arguments[index++]; 
 
     for (var name in properties) 
 
      constructor[name] = properties[name]; 
 
    } 
 

 
    return Object.freeze(constructor); 
 

 
    function constructor(object) { 
 
     for (var name in constructor) 
 
      object[name] = constructor[name]; 
 
     return Object.freeze(object); 
 
    } 
 
} 
 
</script>

this

ずにミックスインを使用してはい、あなたはthisを使用せずに、ミックスインを使用することができます。しかし、あなたがしたいと思う理由を、私は見ていない:

  1. シンプル複数:連結的継承の

    var aircraft = mixin({ 
     
        describeAircraft: function (aircraft) { 
     
         alert("The " + aircraft.model + " flies at " + 
     
          aircraft.speed + " speed."); 
     
        } 
     
    }); 
     
    
     
    var fighterAircraft = mixin(aircraft, { 
     
        describeFighterAircraft: function (fighterAircraft) { 
     
         fighterAircraft.describeAircraft(); 
     
         alert("It has a " + fighterAircraft.radar + " radar signature."); 
     
        } 
     
    }); 
     
    
     
    var superFlanker = fighterAircraft({ 
     
        model: "Super Flanker", 
     
        speed: "Mach 2.25", 
     
        radar: "low" 
     
    }); 
     
    
     
    superFlanker.describeFighterAircraft();
    <script> 
     
    function mixin() { 
     
        var length = arguments.length; 
     
        var index = 0; 
     
    
     
        while (index < length) { 
     
         var properties = arguments[index++]; 
     
         for (var name in properties) 
     
          constructor[name] = properties[name]; 
     
        } 
     
    
     
        return Object.freeze(constructor); 
     
    
     
        function constructor(object) { 
     
         for (var name in constructor) { 
     
          var value = constructor[name]; 
     
          object[name] = typeof value === "function" ? 
     
           value.bind(null, object) : value; 
     
         } 
     
    
     
         return Object.freeze(object); 
     
        } 
     
    } 
     
    </script>

    利点

    composition over inheritanceを好む多くの理由があります。継承。

  2. 高速アクセスが可能です。

私が考えることができる唯一の欠点は、プロトタイプが変更された場合、変更がそのインスタンスに反映されないことです。しかし、とにかくプロトタイプを変更する正当な理由はありません。したがって、私のmixinsはすべて凍結されています。

+0

'this'を使わずにmixinパターンを使うことはできますか? Crockfordのアプローチは、「this」と「new」の両方を避けており、私もそれを達成できるようにしたいと考えています。 – Mathletics

+0

はい、確かに可能です。方法を示すために私の答えを更新しました。しかし、私はそうする理由は見当たりません。 'this'を使って何が問題になったのですか? –

+0

一般に、何も、私はそれを十分に使用します。しかし私の現在のプロジェクトは広告ソフトウェアであり、私は[AdSafe](http://www.adsafe.org/)のガイドラインに従ってみたいと思っています。私の同僚のプログラミングの習慣が必要です。) – Mathletics

関連する問題