我正在尝试创建一个函数,该函数将接受参数arg1, arg2...
,然后将它们传递给新对象C的构造函数,如下所示:new C(arg1, arg2...)
,以便创建C
的新实例用户只需拨打C(arg)
而不是new C(arg)
。这是我的第一次尝试:
var C = function(a){ this.a = a; }
var Cn = function(){
new C.apply(this, arguments);
}
Cn(0) // Should make a new C with a property a equal to 0
new C(0) // ie the same as this
编辑:注意,我需要它来获取任意数量的参数而不使用eval。我正在js中创建一个实现Algebraic Data Types的库。
编辑:解决方案是采用Jeremy's Idea并使其适应无限数量的参数:
var C = function() {
// A unique object so we can identify when we used the 'newless' constructor
var newlessConstructorObj = {}
// Check to see if C has been called with `new`
if(!(this instanceof C))
// If not pass arguments as single arg back to C
return new C(newlessConstructorObj, arguments);
// Check to see if we got here from the line above, if so the arguments were passed in the second arg
var args = (arguments[0] === newlessConstructorObj) ? arguments[1] : arguments
// Do stuff with args
this.a = args[0];
}
C(0);
new C(0);
答案 0 :(得分:2)
如果您希望能够使用或不使用new关键字调用该函数,则必须遵循以下模式:
C = function(a) {
if (!(this instanceof C)) {
return new C(a);
}
this.a = a;
}
所以要创建一个新的“C”实例:
c = new C(a);
和
c = C(a);
将返回正确形成的C
实例答案 1 :(得分:2)
我会在任何一天选择Fabrizio Calderan的解决方案,但因为你想要这个特定的功能 - 这是前辈们告诉我们的:
您可以将参数应用于prototype.constructor
(但使用本机类型(例如Number)时会出现问题):
var Cn = function(){
return C.prototype.constructor.apply(C, arguments);
}
链接:Instantiating a JavaScript object by calling prototype.constructor.apply
或..使用eval
:
function construct(Constructor)
{
/*
* or Array.prototype.slice.call(arguments, 1).map(function() { ... })
* in JavaScript 1.6+, compatibles, and with augmented Array.prototype
*/
var args = [];
for (var i = 1, len = arguments.length; i < len; i++)
{
args[i - 1] = "arguments[" + i + "]";
}
/* or args.join(", ") if you need it pretty-printed */
return eval("new Constructor(" + args + ")");
}
function Foo()
{
window.alert(Array.prototype.slice.call(arguments, 0).join(", "));
}
var f = construct(Foo, /bar/g, {baz: 42});
链接:http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/ff1a104bdc33d5c8
答案 2 :(得分:1)
这样的事情?
var C = function(obj){
var a;
for (a in obj) {
this[a] = obj[a];
}
}
var Cn = function(obj) { return new C(obj); }
instance = Cn({
a : 1,
b : 2
})
instance.a //1
instance.b //2
instance.c //undefined
答案 3 :(得分:1)
如果您不关心正确instanceof
检查,可以尝试:
var C = function(a){ this.a = a; }
var Cn = function(){
return C.apply({}, arguments); // notice an empty object here
}
Cn(0) // Should make a new C with a property a equal to 0
new C(0) // ie the same as this
答案 4 :(得分:1)
使用固定数量的args进行操作很简单:
// assuming one arg
function Cn(arg) {
return new C(arg);
}
// assuming two args
function Cn(arg0, arg1) {
return new C(arg0, arg1);
}
等等。您甚至可以通过迭代参数来创建一个字符串,然后eval
来为任意数量的参数创建一个通用版本。克拉斯,但有效。
但重点是什么?只是为了节省输入4个字符?
答案 5 :(得分:0)
针对ES6进行了更新,您可以使用点差运算符:
var C = function(a){ this.a = a; }
var Cn = function(...args){
return new C(...args);
}
assert.deepStrictEqual(Cn(10), new C(10));