由于无法将new
运算符与arguments
数组(.call或.apply)一起使用,所以我想知道我是否可以手动完成。
在以下代码中,obj1
和obj2
等效(在ES3中)?
function MyClass(a, b, c) {}
var obj1 = new MyClass(2,3,4)
var tmp = function() {}
tmp.prototype = MyClass.prototype;
var obj2 = new tmp;
obj2.constructor = MyClass;
MyClass.call(obj2, 2,3,4);
- edit1 -
您的回答是否意味着上述代码错误或与对象构造等效?
答案 0 :(得分:1)
这个怎么样:
var o = new MyClass;
MyClass.apply(o, args);
您创建的对象通过new关键字正确地从原型继承,然后使用您的参数再次在该对象上调用构造函数。
所有这些要求是你的构造函数构造良好,不会在null
参数上崩溃,并且在同一个对象上多次调用时没有副作用。当然所有这些条件都是正确的,因为你写了正确的单位,对吗?
如果您添加
,请回答您的实际问题 tmp.prototype.constructor = MyClass
然后是obj1和obj2是“相同的”。
答案 1 :(得分:1)
如果您使用的是ES5,则可以使用Object.create()
正确执行此操作:
function MyClass(a) {
console.log('in constructor with param: ' + a);
this.foo = a;
}
var a = new MyClass('a');
var b = Object.create(MyClass.prototype);
b.constructor.apply(b, ['b']);
console.log('a.foo = ', a.foo, ', b.foo = ', b.foo);
console.log(b instanceof MyClass);
输出:
in constructor with param: a
in constructor with param: b
a.foo = a , b.foo = b
true
参见http://jsfiddle.net/Qjfyt/1/,它显示了构造函数只被调用一次,如预期的那样。
答案 2 :(得分:1)
使用以下语法,您应该能够直接应用/调用构造函数而不需要太多模糊。或者在不使用new
运算符的情况下实例化它。
function MyClass(a,b,c){
if (!(this instanceof MyClass)){
return new MyClass(a,b,c)
}
// to demonstrate the arguments are usable using call/apply
this.arg1 = a;
this.arg2 = b;
this.arg3 = c;
}
var obj2 = MyClass.call(null,1,2,3); // or MyClass.apply(null,[1,2,3])
alert([obj2.arg1,obj2.arg2,obj2.arg3].join(',')); //=> 1,2,3
答案 3 :(得分:0)
好吧,您可以使用apply并获取一个几乎与使用new实例化的对象一样的对象:
function MyClass(a, b, c) {this.foo = a;}
var a, b = {}, args = [2, 3, 4]; // notice that b is an Object!
a = new MyClass(2,3,4);
MyClass.prototype.constructor.apply(b, [2, 3, 4]);
console.log('a.foo', a.foo, 'b.foo', b.foo);
正如您所见,这些是等效的,但如果您进一步检查:
console.log('b.constructor === a.constructor', b.constructor === a.constructor);
他们没有相同的构造函数。这是因为b最初是“Object”的一个实例,因为它被设置为一个对象文字,并且它被用作应用于MyClass原型构造函数的上下文。他们将拥有相同的属性/方法,所以也许这足以满足您的需求?
编辑:请参阅下面的@Raynos评论。这种技术意味着你会失去使用MyClass.prototype定义的所有内容。