Javascript对象工厂方法,将参数object作为参数传递

Javascript object factory method that passes arguments object as parameters

本文关键字:object 参数传递 参数 对象 工厂 方法 Javascript      更新时间:2023-09-26

下面的代码不能正常工作(jsFiddle):

function makeFoo(a, b) {
  var foo = new Foo();
  Foo.apply(foo, arguments);
  return foo;
}
var Foo = function(a, b) {
  console.log(
    "This should be called once. "+
    "a='"" + a + "'", " + 
    "b='"" + b + "'", "
  );
  this.a = a;
  this.b = b;
}
Foo.prototype.go = function() {
  console.log("a: " + this.a);
  console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();

期望输出:

应该调用一次。="Hello",b ="世界"
你好
b:世界

实际输出:

应该调用一次。="定义",b ="定义"
这应该被调用一次。="Hello",b ="世界"
你好
b:世界

这是因为您两次调用Foo:通过new和通过函数调用。

我认为对于new Foo(),您只想创建一个继承Foo.prototype的对象。要实现这一点,请使用Object.create(Foo.prototype)

function makeFoo(a, b) {
  var foo = Object.create(Foo.prototype);
  var result = Foo.apply(foo, arguments);
  return Object(result) === result ? result : foo;
}
var Foo = function(a, b) {
  console.log(
    "This should be called once. "+
    "a='"" + a + "'", " + 
    "b='"" + b + "'", "
  );
  this.a = a;
  this.b = b;
}
Foo.prototype.go = function() {
  console.log("a: " + this.a);
  console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();

但这只是一个技巧,您需要在ECMAScript 5中使用它,因为没有办法用任意数量的参数实例化构造函数。

构造函数应该被实例化,而不是作为函数调用。在ECMAScript 6中,您可以使用Reflect.construct

function makeFoo(a, b) {
  return Reflect.construct(Foo, arguments);
}
var Foo = function(a, b) {
  console.log(
    "This should be called once. "+
    "a='"" + a + "'", " + 
    "b='"" + b + "'", "
  );
  this.a = a;
  this.b = b;
}
Foo.prototype.go = function() {
  console.log("a: " + this.a);
  console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();

试试这个:

function makeFoo(a, b){
  var foo = new Foo(a,b);
  return foo;
}