7

EDIT:最後にBergiの答えから分かりました。新しいメンバーの代わりにObject.create()を使用してプライベートメンバーでオブジェクトを作成する方法

ありがとうBergi。

編集:私の質問に対する答えは接線で外れているようです。私は実際には工場に興味がなく、実際には使用しないでください。私の質問は私的な状態に関するものです。 Bergiの答えとコメントから、私は何かを一緒に引くことができると思う。継続する

...

EDIT:Bergiは、以下の質問に答えるために始めたが、最も重要な部分取り残さいる - プライベート状態を。

私は考えをもっと考えていましたが、何らかの工場なしでObject.create()を使ってプライベート状態を達成することができません。しかし、私は間違っていると思うし、Bergiは解決策を暗唱しました... Bergiの答えを出発点として自由に感じてください。

オリジナル:javacriptでnewを避けるための私の探求が私を独特な場所に導いてくれました。私は個人的なオブジェのメンバーがほしいですが、私はObject.create()をあきらめたくありません。

ここにコードがあります。

var trackQueue = {}; 

trackQueue.factory = function() { 
    var that, queue; 
    that = this; 
    queue = []; 

    that.push = function (item) { 
     queue.push(item); 
    }; 

    that.work = function() { 
     document.write(queue + "<br />"); 
    }; 

    return { 
     work : that.work, 
     push : that.push 
    };   
}; 

var a = Object.create(trackQueue.factory()); 
a.push("a"); 
a.push("b"); 
a.push("c"); 

var b = Object.create(trackQueue.factory()); 
b.push("d"); 
b.push("e"); 
b.push("f"); 

a.work(); 
b.work(); 

そしてjsfiddle

http://jsfiddle.net/dsjbirch/Wj6cp/10/

initfactory方法のためのより多くの慣用/適切な名前にしますか?

これは気違いですか?

Be kind - 私の最初の言語ではありません。

+2

なぜ「new」を使いたくないのですか? –

+1

ダグラス・クロフォード。 – bluekeys

+2

それは残念です。 –

答えて

2

はい、プロトタイプのinitメソッドは、より適切な名前かもしれません:

var proto = { 
    init: function(args) { 
     // setting up private-scoped vars, 
     var example = args; 
     // privileged methods 
     this.accessPrivate = function(){ return example; }; 
     // and other stuff 
     this.public = 5; 
    }, 
    prop: "defaultvalue", 
    ... 
} 

var instance = Object.create(proto); 
instance.init(); 

しかし、エレガントObject.createを組み合わせた新しいキーワード、と古典コンストラクタを使用しない理由は絶対にありませんし、 init呼び出し。

Object.createは絶対に使用しないでください。あなたの工場パターン(完全に有効に適用されます)は良いオブジェクトを返します。それらを継承するのそれぞれに新しいオブジェクトを作成する必要はありません。やるだけ:

var instance = trackQueue.factory(); 

メソッド名の音のようなあなたは、「作成」した場合、あなたはあなたの工場のためのより多くの慣用的な名前を使用する可能性があります:

trackQueueFactory.create = function(args) {...}; 

EDIT:あなたのアイデアを組み合わせることプロトタイプ継承を持つファクトリパターンはあまり間違いではありません。しかし、作成されたすべてのオブジェクトが継承するprotoオブジェクトは、ではなく、それぞれの呼び出しで新しいものを作成する代わりに、静的である必要があります。あなたのコードは次のようになります。私は間違っていないよ場合は、これが一つです

var renato = personFactory(1, "Renato Gama", 25); 
console.log(renato.getName()); //logs "Renato Gama" 
renato.setName("Renato Mendonça da Gama"); 
console.log(renato.getName()); //logs "Renato Mendonça da Gama" 

var factory = { 
    proto: { 
     ... 
    }, 
    create: function(args) { 
     var product = Object.create(this.proto); 
     // set up private vars scoped to the create function 
     // privileged methods 
     product.doSomethingSpecial = function(){ ... }; 
     // and other stuff 
    } 
}; 

var a = factory.create(...); 
+0

あなたの例のinit関数でプライベートスコープのバールを設定するにはどうすればよいですか? – bluekeys

+0

通常通り:varキーワードまたは関数宣言を使用します。これらの宣言はinit関数のスコープになります。 – Bergi

2

私は、これはあなたの要件を達成するための明確な方法だと思います:

var personFactory = function(id, name, age){ 
    var _id = id; 
    var _name = name; 
    var _age = age; 

    var personPrototype = { 
     getId: function(){ 
      return _id; 
     }, 
     setId: function(id){ 
      _id = id; 
     }, 
     getName: function(){ 
      return _name; 
     }, 
     setName: function(name){ 
      _name = name; 
     }, 
     getAge: function(){ 
      return _age; 
     }, 
     setAge: function(age){ 
      _age = age; 
     }, 
     work: function(){ 
      document.write(this.toString()); 
     }, 
     toString: function(){ 
      return "Id: " + _id + " - Name: " + _name + " - Age: " + _age; 
     } 
    }; 

    return Object.create(personPrototype); 
}; 

使い方MODULE PATTERNが使用されます。より良い説明については、this postを参照してください。 Thisもまたこの件に関する良い記事です。

+0

いいえ、間違っています。あなたはOPと同じエラーを出しました:私のスコープを考慮したオブジェクトに対してObject.createを使う必要は全くありません。 – Bergi

+0

私はあなたのポイントを得ることができません、少し明確にできますか?なぜそのエラーと見なすことができません。私はあなたのプロトタイプが工場の公衆のメンバーであるという事実とは違って、私が書いたものと似たような2番目のコードブロックを考えています。ファクトリオブジェクトがより多くのパブリック関数を持つが、create()メソッドを持つ場合は、私のアプローチに同意します。 – renatoargh

+0

なぜオブジェクトリテラル( "personPrototype")を直接返さないのですか?あなたのコードでObject.createをどのように使うのですか? – Bergi

関連する問題