以下代码无法正常运行(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();





预期产量:


  这应该被调用一次。 a =“ Hello”,b =“ World”
  答:你好
  b:世界


实际输出:


  这应该被调用一次。 a =“ undefined”,b =“ undefined”
  这应该被调用一次。 a =“ Hello”,b =“ World”
  答:你好
  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();





但这只是一个hack,您需要在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();

关于javascript - 将参数对象作为参数传递的Javascript对象工厂方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39044209/

10-12 00:21
查看更多