2017-04-19 18 views
3

私のnodejsプログラムでは、私はpersonというモジュールを持っていて、その子メソッド(describe)も持つprototypeオブジェクト(about)を持っています。私はオブジェクトのプロパティにアクセスしようとしていますが、私は定義されていません。nodejs/javascriptの再帰的プロトタイプ継承

私の理解を訂正できますか?私はここで間違っていますか?

index.js

var Person = require("./person"); 
var sam = new Person({name:"Sam",age:23}) 
sam.about.describe(); 

person.js

module.exports = (function() { 
    var person = function(options) { 
     if (options && options.name) this.name = options.name; 
     if (options && options.age) this.age = options.age; 
    } 
    person.prototype.about = { 
     describe : function(){ 
      console.log("I am",this.name,"and",this.age,"years old"); 
     } 
    } 
    return person; 
})(); 

予想される出力: 実際の出力 "私はサムと23歳です": "私は未定義と未定義歳"

+0

ザッツを呼び出すことができますこの方法です。プロトタイプのオブジェクトも副作用の可能性があります – Rajesh

+0

ここでは再帰的なものは何ですか? –

+0

@torazaburo ..ごめんなさい、実際には再帰的ではありません.. –

答えて

1

あなたの例では、thisはaboutオブジェクトを参照し、personインスタンス自体は参照していません。

希望のAPIを持つ1つの方法は、コンストラクタ内にそのabout名前空間を作成し、bindを使用してdescribeハンドラに正しいコンテキストを設定することです。

module.exports = (function() { 
    var person = function(options) { 
     if (options && options.name) this.name = options.name; 
     if (options && options.age) this.age = options.age; 
     this.about = { 
      describe: function() { 
       console.log("I am",this.name,"and",this.age,"years old"); 
      }.bind(this) 
     }; 
    } 

    return person; 
})(); 

this`は `about`なく` person`を指している `ので、あなたは、単に

var Person = require("./person"); 
var sam = new Person({name:"Sam",age:23}) 
sam.about.describe(); 

>>> I am Sam and 23 years old 
1

thisは、describeの直接の親を指します。about

です
person.prototype.about = { 
     describe : function() { 
      console.log("I am",this.name,"and",this.age,"years old"); 
     } 
} 

あなたは、例えばabout名前空間に渡されたメインPersonオブジェクトへの弱参照を必要とし、thisの代わりにそれを使うだろう。しかし、私はそれが好きではない、それはcircumvoluted、間違っていると感じ、臭いに見えます。

代わりに、ちょうどそれが完全に新しい機能パッケージは、Personオブジェクトに追加されますという事実をaknowledgeとのそれのためにヘルパーを作成してみましょうみましょう:

module.exports = (function() { 
    var PersonHelper = function(person) { 
     this.person = person; 
     describePerson: function() { 
      console.log("I am",this.person.name,"and",this.person.age,"years old"); 
     } 
     /* more methods */ 
    } 
    return PersonHelper; 
})(); 

だから、その後、行うことができます:

module.exports = (function() { 
    var person = function(options) { 
     if (options && options.name) this.name = options.name; 
     if (options && options.age) this.age = options.age; 
    } 
    return person; 
})(); 


var Person = require("./person"); 
var PersonHelper = require("./personHelper"); 
var sam = new Person({name:"Sam",age:23}) 
var helper = new PersonHelper(person); 
helper.describePerson(); 
+0

は、記述方法でsamを渡すようなものか?サム。about.describe(sam); function(user){ console.log( "私は"、user.name、 "、"、user.age、 "years old"); } –

+0

これはうまくいくが、ちょっと醜い。おそらく、PersonH​​elperオブジェクトをすべて一緒に使うほうがいいでしょう。それは、記述のような関数を埋め込むことになります。 – Sebas

0

sam.about.describeを実際に使用して、aboutの「名前空間」にメソッドを含める場合は、1つのアプローチは

です210

get内のコンテキストがPersonインスタンスのコンテキストであり、矢印関数がそれを正しく参照するためです。

+0

しかし私の要件として、私は "about"のような複数の関数を含む名前空間が必要です。 –