Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中创建对象时动态控制参数_Javascript_Oop_Factory - Fatal编程技术网

在javascript中创建对象时动态控制参数

在javascript中创建对象时动态控制参数,javascript,oop,factory,Javascript,Oop,Factory,我在javascript中有多个eatable类,例如:食物、饮料、零食。 每个类都需要一组不同的参数。我有另一个factory类,它创建发送给它的可食项的实例 我无法弄清楚如何使用此工厂动态选择可吃项并传递参数(以数组形式) 我提出了两个解决方案: 解决方案1: var factory = function(eatable, argumentList){ var obj = new eatable(argumentList); return obj }; 这是一个问题,因为argum

我在javascript中有多个eatable类,例如:食物、饮料、零食。 每个类都需要一组不同的参数。我有另一个factory类,它创建发送给它的可食项的实例

我无法弄清楚如何使用此工厂动态选择可吃项并传递参数(以数组形式)

我提出了两个解决方案: 解决方案1:

var factory = function(eatable, argumentList){
  var obj = new eatable(argumentList);
  return obj
};
这是一个问题,因为argumentList是一个数组

解决方案2

var factory = function(eatable, argumentList){
  var obj =  eatable.apply({}, argumentList);
  return obj
};
这并不会真正创建可食类型的对象

我真正想要的效果 假设我能够将argumentList转换为js参数类型对象-

var obj = new eatable(argumentList.toArguments());
obj instanceOf eatable; // should return true

请帮忙

您必须提供要应用的上下文,上下文就是您试图将参数应用到的对象。您当前传递的
{}
是Object类型的上下文

var factory = function(eatable, argumentList){
  var obj =  eatable.apply(new Eatable(), argumentList);
  return obj
};

我不能使用没有多态性的工厂,因此如果您没有以扩展
Eatalbe
对象的方式创建这些eatable,您将无法执行此操作。

您可以定义一个函数
init
来初始化对象

function Eatable(){

}

Eatable.prototype.init = function(/** arg1, arg2, arg3 **/){
    //  initialize object
}
厂内功能

var eatable = new Eatable();
eatable.init.apply(eatable, /** pass arguments array here **/);
return eatable;
您可以使用来正确设置原型链:

function factory(eatable, argumentList){
    var obj = Object.create(eatable.prototyope);
    return eatable.apply(obj, argumentList) || obj;
}

基本上就是这样的。

啊,是的。我以前遇到过这个问题-你在JavaScript中。以前也曾提出过类似的问题:

问题很明显-
new
是一个关键字,而不是一个函数;和
apply
只能用于函数。如果
new
是一个函数而不是
关键字
,那么我们可以将它与
apply
结合使用

为了了解如何执行此操作,让我们创建一个名为
new
的函数,它与关键字
new
的功能完全相同:

Function.prototype.new = (function () {
    function Factory(constructor, args) {
        return constructor.apply(this, args);
    }

    return function() {
        Factory.prototype = this.prototype;
        return new Factory(this, arguments);
    };
}());
现在不按如下方式调用构造函数:

var object = new constructor(arg1, ...);
var object = constructor.new(arg1, ...);
var object = Function.new.apply(constructor, [arg1, ...]);
您可以按如下方式调用构造函数:

var object = new constructor(arg1, ...);
var object = constructor.new(arg1, ...);
var object = Function.new.apply(constructor, [arg1, ...]);
你问这样做有什么好处?其实很简单。由于
new
现在是一个函数而不是关键字,因此您可以将其与
apply
结合使用,如下所示:

var object = new constructor(arg1, ...);
var object = constructor.new(arg1, ...);
var object = Function.new.apply(constructor, [arg1, ...]);
因此,您的可食工厂功能现在变为:

var factory = function(eatable, argumentList) {
    var obj = Function.new.apply(eatable, argumentList);
    return obj;
};
编辑:如果您的factory函数所做的只是采用一个
eatable
构造函数和一个
argumentList
并返回
new.apply(eatable,argumentList)
,那么正如Bergi在他的评论中指出的那样,您可以将
工厂定义如下:

var factory = Function.apply.bind(Function.new);

希望这有帮助。

实现这一目标的另一种方法如下-

var _bind = Function.prototype.bind;
var factory = function(_constructor, _argumentList){
  var obj = _bind.apply(_constructor, [null].concat(_argumentList));
  return obj
};


如果必须同时传递对所需“类”的引用和参数列表,那么工厂函数的意义何在?我有一个很长的要初始化的类列表。我不想手动编写初始化它们的代码,而只是传递和数组,其中包含类的引用和必须提供给构造函数的参数。是的,但考虑到当前两种可能的解决方案基本上都是单行函数(不包括return语句)您也可以在处理数组的任何循环中只使用这一行。(虽然是的,但我知道你对这些解决方案不满意。)事实上,这就是我正在做的。列表中的每一项都调用工厂方法。我理解这一点。我是说,当工厂函数的(非常短的)主体可以直接进入您的循环时,工厂函数似乎是多余的。我想您不想更改构造函数,以便它们可以接受数组,您可以使用解决方案1?我想创建一个新的食品、饮料等对象,具体取决于在eatable变量中作为参数传递的内容。Eatable本身不是一个类,“应该是”?不,这只是一种方法——甚至你链接的文章也提到了其他不涉及分类的方法。在JS中,使用duck类型是相当常见的…为什么要强制使用多态性?类之间绝对没有关系。这不适用于
eatable.apply(neweatable(),argumentList)-假设
eatable
可能引用的所有构造函数都将在没有参数的情况下“工作”。@nnnnnn你在问我这个吗?什么是eatable?在我的问题中,Eatable只是一个变量,而不是一个类。但是你可以将这个想法应用到你的
Food()
零食()
,等等。类:将每个类定义为一个空构造函数,并带有一个关联的
init()
function…@Tushar Mathur:我刚才使用了
Eatable
作为类定义,只是为了演示如何使用
apply
调用单独的
init
方法,并将参数作为参数传递。@nnnnnn我为什么要用空构造函数修改现有类?这不是一个解决方案,它是一个替代方案,将导致所有类中的更改。您为什么要这样做?因为这是实现工厂函数概念的一种方法,工厂函数可以传递参数。我只是想通过解释这个概念如何与类相关来回答您的第一个评论,而不是说这对您来说一定是最好的选择。
var factory=Function.prototype.apply.bind(Function.prototype.new):-)顺便说一句,如果你已经发现了这个问题,不要忘记投票以重复的方式关闭…@Bergi你也可以做
var factory=Function.apply.bind(Function.new)函数
本身是
函数的一个实例。原型
。真是一个难题。哦,当然。一开始我以为你是在依赖:-/这是一个完美的解决方案!为了更基本的情况,我需要它,所以我做了
var obj=Object.create(MyClass.prototype);返回MyClass.apply(obj,Array.prototype.slice.call(arguments))| | obj@VictorFerreira:不知道我的代码有什么不同?请注意,
切片
是无效的