2017-04-17 43 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/