当您编写ES6类时,可以在构造函数中使用解构,以便更容易使用默认选项:
class Person {
constructor({
name = "Johnny Cash",
origin = "American",
profession = "singer"
} = {}) {
this.name = name;
this.origin = origin;
this.profession = profession;
}
toString() {
return `${this.name} is an ${this.origin} ${this.profession}`;
}
}
这可以让你做到这样的事情:
const person = new Person();
console.log(person.toString());
// Returns 'Johnny Cash is an American singer'
const nina = new Person({
name : "Nina Simone"
})
console.log(nina.toString());
// Returns 'Nina Simone is an American singer'
但是,您需要在构造函数中重复参数以将它们分配给类实例。我已经发现你可以做到这一点,以减少冗长:
Object.assign(this, { name, origin, profession });
但是你仍然需要重复这三个变量。有没有办法让分配更短而不重复变量?
答案 0 :(得分:3)
您可以让构造函数接受一个“config”参数,然后说出Object.assign(this, config)
。要拥有默认值,您只需设置默认对象,或将它们作为类属性分配给构造函数外部。
编辑致T.J.克劳德的观点,从技术上讲,使用Object.assign()
时传入的任何内容都会被添加到您的对象中,这可能在很多方面都有害。我添加了一种方法来剥离配置对象,使其仅包含您定义的一组属性。 T.J.的解决方案也适用,我只是做了不同的选择,所以你有选择。
function stripObjToModel(model, obj) {
// this method will modify obj
Object.keys(obj).forEach(function (key) {
if (!model.hasOwnProperty(key)) {
delete obj[key];
}
});
return obj;
}
class Person {
constructor(config = {}) {
var defaults = {
name: "Johnny Cash",
origin: "American",
profession: "singer"
};
Object.assign(this, defaults, stripObjToModel(defaults, config));
}
toString() {
return `${this.name} is an ${this.origin} ${this.profession}`;
}
}
const person = new Person();
console.log(person.toString());
// Returns 'Johnny Cash is an American singer'
const nina = new Person({
name : "Nina Simone",
foo: "bar",
toString: function () {return "Hello World!";}
})
console.log(nina.toString());
// Returns 'Nina Simone is an American singer'
答案 1 :(得分:0)
可悲的是,我认为没有任何内置方法可以接受具有单独默认值的选项对象,并且只从您收到的对象中获取这些属性(而不是其他可能指定的外来属性)而不重复自己。这很不幸。 (这也不是我第一次想要解构和对被解构对象的引用。)
这意味着我们必须自己出去,但这很简单:
function applyDefaults(target, options, defaults) {
for (const key in defaults) { // Or `const key of Object.keys(defaults)` for just own props
target[key] = (typeof options[key] === undefined ? defaults : options)[key];
}
}
然后:
constructor(options = {}) {
applyDefaults(this, options, {
name: "Johnny Cash",
origin: "American",
profession: "singer"
});
}
(如果在每个构造函数调用上重新创建对象让你担心,你可以将它移出课堂,但我不会担心它。)
但是然后在方法签名中没有描述单个属性的默认值,对我来说这是足够强大的理由继续并重复你现在拥有的名称。
答案 2 :(得分:0)
不是我提倡它,但你可以在技术上做到
constructor(options = {}) {
({
name: this.name = "Johnny Cash",
origin: this.origin = "American",
profession: this.profession = "singer",
} = options);
}
我个人认为你的示例代码有点重复看起来很好。