我正在创建具有大量属性的对象,并且我对实例化它们的最佳实践感到好奇。拥有真正长的构造函数似乎很糟糕(实例化新对象并不好玩)。
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, ...);

我想知道是否应该在构造函数中设置三个重要的属性(例如,标题,作者和页面),并为其余部分编写单独的setter。或者为了保持一致,我应该只使用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 :(得分:2)
似乎最好使用arguments对象和mixin。这是一种双刃剑,因为它使实例化对象的代码更容易阅读,但构造函数本身不太明显。 e.g。
function Book(args) {
Object.assign(this, args);
}
var rc = new Book({
name: "Robinson Crusoe",
author: "Daniel Defoe",
pages: 342
});
如果你想要默认值,那么你可以用另一个混合实现它,例如
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"
如果要确保提供某些值,则需要在构造函数的末尾测试这些值是否存在并抛出错误。
答案 1 :(得分:2)
在es6中,您可以使用destructuring和Object.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
中的每个属性,仅分配有效参数。
这是否会破坏首先拥有构造函数的目的?如果这是你所做的全部,那么是的。是的,它确实。但希望你的班级除此之外还有一些方法和目的。
答案 2 :(得分:2)
最佳做法是将定义属性的对象传递给构造函数:
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/
答案 3 :(得分:0)
我知道这是一个古老的要求,但我想知道为什么没人提到复杂的对象。我认为,这是组织和存储数据的最简单方法。
function Book({reference, publication, author}) {
this.reference = reference;
this.publication = publication;
this.author = author;
}
var rc = new Book({
reference: {
title: 'Robinson Crusoe',
pages: 342,
chapters: 16,
protagonistFavoriteColor: 'lilac'
},
publication: {
publisher: 'John Smith co.',
date: '04-25-1719'
},
author: {
name: 'Daniel Defoe',
homeTown: 'London'
}
});
console.log(rc.reference.title); // 'Robinson Crusoe'
console.log(rc.publication.date); // '04-25-1719'
console.log(rc.author.name); // 'Daniel Defoe'
此方法还使您可以访问整个类别。
console.log(rc.author); // {name: "Daniel Defoe", homeTown: "London"}
console.log(rc.reference); // {title: "Robinson Crusoe", pages: 342, chapters: 16, protagonistFavoriteColor: "lilac"}
一旦您熟悉此组织,创建对象就很简单又有趣。