为什么 JavaScript ES6 不支持多构造函数类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32626524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't JavaScript ES6 support multi-constructor classes?
提问by Manhhailua
I want to write my Javascript class like below.
我想像下面这样编写我的 Javascript 类。
class Option {
constructor() {
this.autoLoad = false;
}
constructor(key, value) {
this[key] = value;
}
constructor(key, value, autoLoad) {
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
I think it would be nice if we can write out class in this way. Expect to happen:
我想如果我们能这样写出类就好了。预计会发生:
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}
采纳答案by CodingIntrigue
I want to write my Javascript class like below
我想像下面这样编写我的 Javascript 类
You can't, in the same way you can't overload standard functions like that. What you cando is use the argumentsobject to query the number of arguments passed:
你不能,就像你不能重载这样的标准函数一样。您可以做的是使用参数对象来查询传递的参数数量:
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;
}
}
}
Of course (with your updated example), you could take the approach that you don't care about the number of arguments, rather whether each individual value was passed, in which case you could so something like:
当然(使用您更新的示例),您可以采用不关心参数数量的方法,而不必关心是否传递了每个单独的值,在这种情况下,您可以这样做:
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;
}
}
回答by Bardi Harborow
What you want is called constructor overloading. This, and the more general case of function overloading, is not supported in ECMAScript.
你想要的是构造函数重载。ECMAScript 不支持这种情况以及更一般的函数重载情况。
ECMAScript does not handle missing arguments in the same way as more strict languages. The value of missing arguments is left as undefined
instead of raising a error. In this paradigm, it is difficult/impossible to detect which overloaded function you are aiming for.
ECMAScript 不像更严格的语言那样处理丢失的参数。缺少参数的值保留为undefined
而不是引发错误。在这种范式中,很难/不可能检测到您的目标是哪个重载函数。
The idiomatic solution is to have one function and have it handle all the combinations of arguments that you need. For the original example, you can just test for the presence of key
and value
like this:
惯用的解决方案是拥有一个函数并让它处理您需要的所有参数组合。对于原始示例,您可以测试是否存在key
和value
像这样:
class Option {
constructor(key, value, autoLoad = false) {
if (typeof key !== 'undefined') {
this[key] = value;
}
this.autoLoad = autoLoad;
}
}
回答by GFoley83
Another option would be to allow your constructor to take an object that is bound to your class properties:
另一种选择是允许您的构造函数采用绑定到您的类属性的对象:
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}
This is even more useful with Typescript as you can ensure type safety with the values passed in (i.e. key
could only be a string, autoLoad
a boolean etc).
这对于 Typescript 更有用,因为您可以通过传入的值确保类型安全(即key
只能是字符串、autoLoad
布尔值等)。
回答by Diogo Eichert
Guessing from your sample code, all you need is to use default values for your parameters:
从您的示例代码中猜测,您只需要为参数使用默认值:
class Option {
constructor(key = 'foo', value = 'bar', autoLoad = false) {
this[key] = value;
this.autoLoad = autoLoad;
}
}
Having said that, another alternative to constructor overloading is to use static factories. Suppose you would like to be able to instantiate an object from plain parameters, from a hash containing those same parameters or even from a JSON string:
话虽如此,构造函数重载的另一种替代方法是使用静态工厂。假设您希望能够从普通参数、包含这些相同参数的散列或什至从 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}');
回答by Diogo Eichert
Here's a hack for overloading based on arity (number of arguments). The idea is to create a function from a number of functions with different arities (determined by looking at fn.length
).
这是一个基于 arity(参数数量)的重载技巧。这个想法是从多个具有不同元数的函数(通过查看 确定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);
Of course this needs a lot of bullet-proofing and cleaning up, but you get the idea. However, I don't think you'll have much luck applying this to ES6 class constructors, because they are a horse of a different color.
当然,这需要大量的防弹和清理工作,但您懂的。但是,我认为将其应用于 ES6 类构造函数不会有太大的运气,因为它们是不同颜色的马。
回答by mahdi shahbazi
you can use static methods,look at 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)
回答by Azat
Use object.assigne
with arguments with this
object.assigne
与参数一起使用
This={...this,...arguments}