以下代码无法正常工作(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 ="你好",b ="世界"
a:你好 b:世界
实际输出:
应该调用一次。 a =" undefined",b =" undefined"
这应该被调用一次。 a ="你好",b ="世界"
a:你好 b:世界
答案 0 :(得分:6)
这是因为您拨打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();
答案 1 :(得分:0)
试试这个:
function makeFoo(a, b){
var foo = new Foo(a,b);
return foo;
}