我想写下我的Javascript类。
class Option {
constructor() {
this.autoLoad = false;
}
constructor(key, value) {
this[key] = value;
}
constructor(key, value, autoLoad) {
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
我认为如果我们能以这种方式写出课程会很好。 期待发生:
var option1 = new Option(); // option1 = {autoLoad: false}
var option2 = new Option('foo', 'bar',); // option2 = {foo: 'bar'}
var option3 = new Option('foo', 'bar', false); // option3 = {foo: 'bar', autoLoad: false}
答案 0 :(得分:27)
我想写下我的Javascript类
你不能以同样的方式超载标准功能。您可以做的是使用arguments对象来查询传递的参数数量:
class Option {
constructor(key, value, autoLoad) {
// new Option()
if(!arguments.length) {
this.autoLoad = false;
}
// new Option(a, [b, [c]])
else {
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
}
当然(使用您的更新示例),您可以采用您不关心参数数量的方法,而不是每个单独的值是否通过,在这种情况下,您可能会这样:
class Option {
constructor(key, value, autoLoad) {
if(!key) { // Could change this to a strict undefined check
this.autoLoad = false;
return;
}
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
答案 1 :(得分:17)
你想要的是构造函数重载。 ECMAScript不支持这种情况以及function overloading的更一般情况。
ECMAScript不像更严格的语言那样处理缺少的参数。缺少参数的值保留为undefined
,而不是引发错误。在这个范例中,很难/不可能检测出你想要的过载功能。
惯用解决方案是拥有一个函数并让它处理您需要的所有参数组合。对于原始示例,您可以像这样测试key
和value
的存在:
class Option {
constructor(key, value, autoLoad = false) {
if (typeof key !== 'undefined') {
this[key] = value;
}
this.autoLoad = autoLoad;
}
}
答案 2 :(得分:6)
这是基于arity(参数数量)的重载黑客攻击。我们的想法是使用不同的arities创建一个函数(通过查看fn.length
确定)。
function overloaded(...inputs) {
var fns = [];
inputs.forEach(f => fns[f.length] = f);
return function() {
return fns[arguments.length].apply(this, arguments);
};
}
var F = overloaded(
function(a) { console.log("function with one argument"); },
function(a, b) { console.log("function with two arguments"); }
);
F(1);
F(2, 3);
当然,这需要大量的防弹和清理,但你明白了。但是,我不认为你将这个应用于ES6级构造函数会有很多运气,因为它们是一匹不同颜色的马。
答案 3 :(得分:5)
另一种选择是允许构造函数获取绑定到类属性的对象:
class Option {
// Assign default values in the constructor object
constructor({key = 'foo', value, autoLoad = true} = {}) {
this.key = key;
// Or on the property with default (not recommended)
this.value = value || 'bar';
this.autoLoad = autoLoad;
console.log('Result:', this);
}
}
var option1 = new Option();
// Logs: {key: "foo", value: "bar", autoLoad: true}
var option2 = new Option({value: 'hello'});
// Logs: {key: "foo", value: "hello", autoLoad: true}

这对使用Typescript更有用,因为您可以使用传入的值确保类型安全(即key
只能是字符串,autoLoad
是布尔等。)
答案 4 :(得分:2)
从示例代码中猜测,您只需要为参数使用默认值:
class Option {
constructor(key = 'foo', value = 'bar', autoLoad = false) {
this[key] = value;
this.autoLoad = autoLoad;
}
}
话虽如此,构造函数重载的另一种替代方法是使用静态工厂。假设您希望能够从普通参数,包含相同参数的哈希或甚至JSON字符串中实例化对象:
class Thing {
constructor(a, b) {
this.a = a;
this.b = b;
}
static fromHash(hash) {
return new this(hash.a, hash.b);
}
static fromJson(string) {
return this.fromHash(JSON.parse(string));
}
}
let thing = new Thing(1, 2);
// ...
thing = Thing.fromHash({a: 1, b: 2});
// ...
thing = Thing.fromJson('{"a": 1, "b": 2}');
答案 5 :(得分:1)
您可以使用静态方法,请查看my answer to same question
class MyClass {
constructor(a,b,c,d){
this.a = a
this.b = b
this.c = c
this.d = d
}
static BAndCInstance(b,c){
return new MyClass(null,b,c)
}
}
//a Instance that has b and c params
MyClass.BAndCInstance(b,c)
答案 6 :(得分:0)
将此参数与object.assigne
一起使用
This={...this,...arguments}
答案 7 :(得分:0)
这不是我想要的重载,但这是我如何通过创建具有一些不同初始化行为的obj1来伪造自己方式的基本版本。我意识到我可以像上面所说的那样扩展论据,但是我已经有了一组令人讨厌的论据和相对不同的数据源来解构,这实际上会扭曲我的目标。这只是让它更适合我的情况...
class obj1{
constructor(v1, v2){
this.a = v1;
this.b = v2;
}
}
class obj1Alt{
constructor(v1, v2){
return new obj1(v1*2,v2*2);
}
}
new obj1(2,4) // returns an obj1
new obj1Alt(2,4) // also returns an obj1
免责声明:我已经进行了很长时间的编程,但是对JS来说我还很陌生。可能不是最佳做法。