2017-04-17 44 views
5

我正在創建具有很多屬性的對象,我很好奇實例化它們的最佳實踐。看起來真的有很長的構造函數是很糟糕的(實例化新對象並不好玩)。JavaScript中長構造函數的最佳實踐

function Book(title, author, pages, chapters, publisher, datePublished, authorHometown, protagonistFavoriteColor) { 
 
    this.title = title; 
 
    this.authorpages = authorpages; 
 
    this.pages = pages; 
 
    this.chapters = chapters; 
 
    this.publisher = publisher; 
 
    this.datePublished = datePublished; 
 
    this.authorHometown = authorHometown; 
 
    this.protagonistFavoriteColor = protagonistFavoriteColor; 
 
} 
 

 
// not reliable to remember how to order params 
 
var rc = new Book("Robinson Crusoe", "Daniel Defoe", 342, 16, ...);

如果也許我應該只是在構造函數(e.g.title,作者和頁)設置也許三個重要特性,寫的其他個人制定者我不知道。或者爲了一致性,我應該只使用setter?如果以這種方式進行設置是最佳路徑,那麼在JS中是否有一種很好的方式來命令調用這些方法(有點像Java中的接口)?

function Book (title, author, pages){ 
 
    this.title = title; 
 
    this.author = author; 
 
    this.pages = pages; 
 
    this.chapters = null; 
 
    this.publisher = null; 
 
    this.datePublished = null; 
 
    this.authorHometown = null; 
 
    this.protagonistFavoriteColor = null; 
 
} 
 

 
var rc = new Book("Robinson Crusoe", "Daniel Defoe", 342); 
 
rc.setChapters(16); 
 
rc.setPublisher("John Smith Co."); 
 
rc.setDatePublished("04-25-1719"); 
 
rc.setAuthorHometown("London"); 
 
rc.setProtagonistFavoriteColor("lilac"); 
 
// we'd also want to mandate that these setters be called so nothing is left null

最後,將傳遞一個對象到我的構造函數和解構它完敗構造的PT?

+0

在施工的時候,你有(或必須)所有的值之前創建對象的實例? - 我知道在某些情況下,您希望使用您手邊的信息獲取實例,然後從數據源或用戶輸入中獲取其餘部分(如果需要)。如果是這種情況,我會推薦builder模式 - 以這個小提琴爲例:https://jsfiddle.net/brandonscript/p516ojn0/ – ochi

回答

1

似乎最好使用參數對象和mixin。這是一把雙刃劍,它使得實例化對象的代碼更易於閱讀,但構造器本身不太明顯。例如

function Book(args) { 
    Object.assign(this, args); 
} 

var rc = new Book({ 
    name: "Robinson Crusoe", 
    author: "Daniel Defoe", 
    pages: 342 
}); 

如果你想要默認值,那麼你可以用另一個mixin來實現,例如,

function Book(args) { 
    args = Object.assign(args, { 
     protagonistFavoriteColor: "Red" 
    }); 

    Object.assign(this, args); 
} 

然後調用如:

var rc = new Book({ 
    name: "Robinson Crusoe", 
    author: "Daniel Defoe", 
    pages: 342 
}); 

還會送:

rc.author; // "Daniel Defoe" 
rc.protagonistFavoriteColor // "Red" 

如果你想提供確保一定的值,則需要在年底進行測試那些存在的構造函數並拋出一個錯誤。

2

在ES6你可以使用destructuringObject.assign簡化拷貝構造圖(構造函數進行參數載貨對象作爲它的唯一參數):

function Book({title, author, pages, chapters, publisher, datePublished, 
 
       authorHometown, protagonistFavoriteColor}) { 
 
    Object.assign(this, {title, author, pages, chapters, publisher, datePublished, 
 
         authorHometown, protagonistFavoriteColor}); 
 
} 
 

 
var rc = new Book({title: "Robinson Crusoe", author: "Daniel Defoe", 
 
        pages: 342, chapters: 16}); 
 

 
var copy = new Book(rc); 
 

 
console.log(JSON.stringify(rc)); 
 
console.log(JSON.stringify(copy)); 
 
console.log(copy == rc); // false

這就是所謂的是,因爲您現在可以方便地從另一個實例創建一個對象。

我們列舉Object.assign中的每個屬性,只分配有效的參數。

這是否破壞了首先有構造函數的目的?如果這是你所有的課程,那麼是的。是的,它確實。但希望你的班級除了這個之外還有一些方法和目的。

1

最好的做法是通過定義屬性到構造一個對象:

function Book(props) { 
    // create variables out of object (if you need to) 
    const { 
    title, 
    author, 
    pages, 
    chapters, 
    publisher, 
    datePublished, 
    authorHometown, 
    protagonistFavoriteColor 
    } = props; 

    // assign properties to instance object 
    Object.assign(this, props); 
} 

const rc = new Book({ 
    title: "Robinson Crusoe", 
    author: "Daniel Defoe", 
    pages: 342, 
    chapters: 16, 
    // rest of properties 
}); 

console.log(rc); 

的jsfiddle演示:https://jsfiddle.net/Lr6umykn/3/