多个构造函数的 JavaScript 模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3220721/
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
JavaScript pattern for multiple constructors
提问by codeholic
I need different constructors for my instances. What is a common pattern for that?
我的实例需要不同的构造函数。什么是常见的模式?
采纳答案by codeholic
How do you find this one?
你怎么找到这个?
function Foobar(foobar) {
this.foobar = foobar;
}
Foobar.prototype = {
foobar: null
};
Foobar.fromComponents = function(foo, bar) {
var foobar = foo + bar;
return new this(foobar);
};
回答by bobince
JavaScript doesn't have function overloading, including for methods or constructors.
JavaScript 没有函数重载,包括方法或构造函数。
If you want a function to behave differently depending on the number and types of parameters you pass to it, you'll have to sniff them manually. JavaScript will happily call a function with more or fewer than the declared number of arguments.
如果您希望函数根据传递给它的参数的数量和类型而表现出不同的行为,则必须手动嗅探它们。JavaScript 会很高兴地调用一个函数,其参数数量多于或少于声明的数量。
function foo(a, b) {
if (b===undefined) // parameter was omitted in call
b= 'some default value';
if (typeof(a)==='string')
this._constructInSomeWay(a, b);
else if (a instanceof MyType)
this._constructInSomeOtherWay(a, b);
}
You can also access argumentsas an array-like to get any further arguments passed in.
您还可以arguments像数组一样访问以获取传入的任何其他参数。
If you need more complex arguments, it can be a good idea to put some or all of them inside an object lookup:
如果您需要更复杂的参数,最好将部分或全部参数放入对象查找中:
function bar(argmap) {
if ('optionalparam' in argmap)
this._constructInSomeWay(argmap.param, argmap.optionalparam);
...
}
bar({param: 1, optionalparam: 2})
Python demonstrates how default and named arguments can be used to cover the most use cases in a more practical and graceful way than function overloading. JavaScript, not so much.
Python 演示了如何使用默认参数和命名参数以比函数重载更实用和优雅的方式覆盖大多数用例。JavaScript,不是那么多。
回答by Jacob McKay
Didn't feel like doing it by hand as in bobince's answer, so I just completely ripped off jQuery's plugin options pattern.
不想像 bobince 的回答那样手工完成,所以我只是完全撕掉了 jQuery 的插件选项模式。
Here's the constructor:
这是构造函数:
//default constructor for Preset 'class'
function Preset(params) {
var properties = $.extend({
//these are the defaults
id: null,
name: null,
inItems: [],
outItems: [],
}, params);
console.log('Preset instantiated');
this.id = properties.id;
this.name = properties.name;
this.inItems = properties.inItems;
this.outItems = properties.outItems;
}
Here's different ways of instantiation:
以下是不同的实例化方式:
presetNoParams = new Preset();
presetEmptyParams = new Preset({});
presetSomeParams = new Preset({id: 666, inItems:['item_1', 'item_2']});
presetAllParams = new Preset({id: 666, name: 'SOpreset', inItems: ['item_1', 'item_2'], outItems: ['item_3', 'item_4']});
And here's what that made:
这就是这样做的:
presetNoParams
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]}
presetEmptyParams
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]}
presetSomeParams
Preset {id: 666, name: null, inItems: Array[2], outItems: Array[0]}
presetAllParams
Preset {id: 666, name: "SOpreset", inItems: Array[2], outItems: Array[2]}
回答by mahdi shahbazi
you can use class with static methods that return an instance of that class
您可以将类与返回该类实例的静态方法一起使用
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)
}
static BAndDInstance(b,d){
return new MyClass(null,b, null,d)
}
}
//new Instance just with a and other is nul this can
//use for other params that are first in constructor
const myclass=new MyClass(a)
//an Instance that has b and c params
const instanceWithBAndC = MyClass.BAndCInstance(b,c)
//another example for b and d
const instanceWithBAndD = MyClass.BAndDInstance(b,d)
with this pattern you can create multi constructor
使用此模式,您可以创建多构造函数
回答by laughingbovine
Going further with eruciform's answer, you can chain your newcall into your initmethod.
进一步使用 eruciform 的答案,您可以将您的new调用链接到您的init方法中。
function Foo () {
this.bar = 'baz';
}
Foo.prototype.init_1 = function (bar) {
this.bar = bar;
return this;
};
Foo.prototype.init_2 = function (baz) {
this.bar = 'something to do with '+baz;
return this;
};
var a = new Foo().init_1('constructor 1');
var b = new Foo().init_2('constructor 2');
回答by eruciform
Sometimes, default values for parameters is enough for multiple constructors. And when that doesn't suffice, I try to wrap most of the constructor functionality into an init(other-params) function that is called afterwards. Also consider using the factory concept to make an object that can effectively create the other objects you want.
有时,参数的默认值对于多个构造函数就足够了。如果这还不够,我会尝试将大部分构造函数功能包装到一个 init(other-params) 函数中,然后再调用。还可以考虑使用工厂概念来制作一个可以有效创建您想要的其他对象的对象。
http://en.wikipedia.org/w/index.php?title=Factory_method_pattern&oldid=363482142#Javascript
http://en.wikipedia.org/w/index.php?title=Factory_method_pattern&oldid=363482142#Javascript
回答by DalSoft
Answering because this question is returned first in google but the answers are now outdated.
回答是因为这个问题首先在谷歌中返回,但答案现在已经过时了。
You can use Destructuring objects as constructor parameters in ES6
您可以在 ES6 中使用Destructuring 对象作为构造函数参数
Here's the pattern:
这是模式:
You can't have multiple constructors, but you can use destructuring and default values to do what you want.
你不能有多个构造函数,但你可以使用解构和默认值来做你想做的事。
export class myClass {
constructor({ myArray = [1, 2, 3], myString = 'Hello World' }) {
// ..
}
}
And you can do this if you want to support a 'parameterless' constructor.
如果您想支持“无参数”构造函数,则可以执行此操作。
export class myClass {
constructor({myArray = [1, 2, 3], myString = 'Hello World'} = {}) {
// ..
}
}
回答by Arsen Ablaev
export default class Order {
static fromCart(cart) {
var newOrder = new Order();
newOrder.items = cart.items;
newOrder.sum = cart.sum;
return newOrder;
}
static fromOrder(id, order) {
var newOrder = new Order();
newOrder.id = id;
newOrder.items = order.items;
newOrder.sum = order.sum;
return newOrder;
}
}
Useges:
用途:
var newOrder = Order.fromCart(cart)
var newOrder = Order.fromOrder(id, oldOrder)
回答by Simon Stanford
This is the example given for multiple constructors in Programming in HTML5 with JavaScript and CSS3 - Exam Ref.
这是使用 JavaScript 和 CSS3 进行 HTML5 编程 - 考试参考中为多个构造函数提供的示例。
function Book() {
//just creates an empty book.
}
function Book(title, length, author) {
this.title = title;
this.Length = length;
this.author = author;
}
Book.prototype = {
ISBN: "",
Length: -1,
genre: "",
covering: "",
author: "",
currentPage: 0,
title: "",
flipTo: function FlipToAPage(pNum) {
this.currentPage = pNum;
},
turnPageForward: function turnForward() {
this.flipTo(this.currentPage++);
},
turnPageBackward: function turnBackward() {
this.flipTo(this.currentPage--);
}
};
var books = new Array(new Book(), new Book("First Edition", 350, "Random"));

