javascript protoypal 継承がどのように機能するかを理解する助けが必要です...または、期待どおりに機能しない理由を理解する必要があります。
基本的に、new
ステートメントから返されるテンプレート化されたオブジェクトを確立しようとしています。utils.js
パラメーター オブジェクトから対応するテンプレート オブジェクトに任意の値を代入する汎用コンストラクター関数がモジュールにあり、呼び出しの結果としてその変更されたテンプレート オブジェクトを返しますnew
。
module.exports.ctor = ctor;
//Mapped object constructor
function ctor(template) {
return function(args) {
var s, t, p;
//guard against being used without new
//courtesy of John Resig http://ejohn.org/blog/simple-class-instantiation/
if (!(this instanceof arguments.callee)) {
throw new Error("Constructor called without 'new'");
}
//create a deep copy of `template` to modify
t = JSON.parse(JSON.stringify(template));
args = args === 'undefined' ? {} : args;
// copy values of matching properties from `args` to `t`
// (uses Crockford's `typeOf` function http://javascript.crockford.com/remedial.html)
for (p in t) {
if (args[p]) {
s = typeOf(t[p]);
if (s === 'function' || s === 'null') {
/* do nothing */
} else if (s === 'array') {
t[p] = t[p].concat(args[p]);
} else {
t[p] = args[p];
}
}
}
return t;
};
}
オブジェクトにいくつかの特定のプロパティを追加して、ジェネリック コンストラクターがContact
テンプレート オブジェクトでどのように動作するかの例を次に示します。Contact
prototype
var template = {
email: null,
phone: null,
address: []
};
var Contact = require('../util').ctor(template);
Contact.prototype.template = template;
Contact.prototype.print = function() {
var str = this.email + '\n';
str += this.phone + '\n';
for (var i = 0; i < this.address.length; i++) {
str += this.address[i].toString() + '\n';
}
};
module.exports = Contact;
私の期待は、template
プロパティとprint
関数が返されたオブジェクトのチェーンで利用可能になることですが、そうではないようです (ノード REPL から):
> var Contact = require('./mapping/Contact');
undefined
> var c = new Contact();
undefined
> c.print
undefined
> c.template
undefined
> c
{ email: '', phone: '', address: [] }
Contact
のプロトタイプにプロパティを明示的に追加している場合、返されたオブジェクトでそれらのプロパティを使用できない理由を誰かが説明できますか?