最初のものはコンストラクターであるため、によって拡張でき、結果がこのタイプのインスタンスであるかどうprototype
かをテストできます。instanceof
欠点: - キーワードを忘れるとnew
、コードが爆発します (そのための回避策をそれぞれに書かない限りconstuctor
)
apply()
また、新しいオブジェクトをインスタンス化するときに、コンストラクターを使用して引数の配列を渡すことは実際にはできません。一方、たとえできる/できたとしても、それをしないでください。
2 つ目は、コンストラクターではなくファクトリーです。-キーワードを使用するかどうnew
かに関係なく。この実装では、同じように見えるが型やプロトタイプを共有しないオブジェクトを作成します (ただし、基礎となる JS エンジンはそれらを類似していると認識し、同じプロパティを持っている限り、同じ隠しクラスを共有します。同じ順序、... 別のトピック)
簡単に言えば、パフォーマンスもメモリフットプリントも、このアプローチの影響を受けません (もう)
ただし、それらが同じタイプであるかどうかを確認することはできず、すべてのインスタンスに影響を与える可能性のある共有プロトタイプはありません (おそらく長所または短所です)。
私のgotoアプローチ継承が必要な場合は、両方を組み合わせたものです
(データオブジェクトが必要な場合は、通常、ファクトリとプレーンオブジェクトを使用します)。
function Book(conf) {
var book = Object.create(Book.prototype);
//a book like this usually has multiple configs/properties
if(typeof conf === "object"){
for(var k in conf) book[k] = conf[k];
}else if(conf){
//assuming that I get at least the name passed
book.name = String(conf);
}
return book;
}
//I have a prototype that can be extended
//with default-values for example; no idea for a good method
//to add to the prototype in this example ;)
Book.prototype.numPages = 0;
//but I can also use it like a plain function; no error if you
var myBook1 = Book("Peter Pan");
var myBook2 = Book({
name: "American Gods",
author: "Neil Gaiman"
});
次の行を関数の先頭に追加すると、それをメソッドとして使用して、Book
既存のインスタンスを複製せずに何でもインスタンスにキャストすることもできます
function Book(conf) {
//with this simple line I can also use this as a function to cast anything into a "Book"
if(conf instanceof Book) return conf;
var book = Object.create(Book.prototype);
//...
return book;
}
var data = [
"Peter Pan",
{name: "American Gods"},
//...
];
var books = data.map(Book);
私の意見では、このアプローチには両方の利点があります。