我正在编写一个jquery lib,我需要实现Datetime函数。 我需要创建一个返回新Date对象的.Date()函数。
如何将我的.Date(args)函数的参数传递给Date对象构造函数,以便创建一个新的日期对象?
我试过这样的东西,我是插件名称空间,我= $ .jqGUI。
//.Date(Value)
/* Return a date object.
* ReturnValue = Date(Value)
*/
me.Date = function(Value){
//pass arguments to Date constructor
var sDate = Date.prototype.constructor.apply(null, arguments);
console.log(sDate);
//create a date object d
var d = new Date(sDate);
//validate date object
if(d.toDateString()=="Invalid Date"){
throw new Error("$.jqGUI.Date: Invalid Date");
}
else{
return d;
}
};
这里我向Date.prototype.constructor传递参数,但无论如何我都得到当前日期。 如果arguments是日期字符串,则忽略它。 为什么呢?
答案 0 :(得分:6)
var args = Array.prototype.concat.apply([null], arguments);
return new (Function.prototype.bind.apply(Date, args));
如果您的目标浏览器不支持ECMAScript 5 Function.prototype.bind,则代码将不起作用。但这不太可能,请参阅compatibilty table。
答案 1 :(得分:2)
Date.prototype.constructor
没用,只需使用Date
- 函数是的构造函数。
.apply(null, ...
您需要在该类型的新创建的对象上应用构造函数,而不是null
。见Use of .apply() with 'new' operator. Is this possible?
但是,不可能应用真正的Date
构造函数(用于new
的函数),因为EcmaScript指定当Date
作为函数调用时它必须返回当前UTC时间。
无论如何,你不应该需要这个。您应该只将参数指定为Date
对象,而不是接收一堆参数(可变大小)。该函数的用户可以构建他想要的方式。
你奇怪的函数似乎与Date
构造函数完全相同。扔掉它,让用户自己申请Date
- 他知道他想要哪种格式。
此外,您不应该使用if(d.toDateString()=="Invalid Date")
,这不是标准化的,而是依赖于实现的。要检查有效的Date
对象,只需使用isNaN
- 不可解析日期的内部表示(Date
实例的值)为NaN
。
建议:
me.date = function(d) {
/* gets: a Date object or something that can be transformed to a Date
returns: a valid Date object, else throws an Error */
d = new Date(d); // works also for Date instances, uncouples them
// else creates new one from string or number
if (isNaN(d))
throw new Error("$.jqGUI.Date: Invalid Date");
return d;
};
答案 2 :(得分:0)
一些注意事项:
eval
,这很危险。bind
并非始终可用,并且正如所指出的那样,垫片也不会起作用。Date.UTC
还接受一个变量参数列表,并返回一个可供Date
构造函数使用的标量。apply
只需要一个像对象一样的数组,而不是一个实际的数组,所以arguments
已经足够了。所以这是我首选的,浏览器安全,完全可变的方法。注意它如何处理Date.now()
的参数。传递null
与没有参数不同,因此允许执行相同的操作。
me.Date = function(value){
if (arguments.length < 1) value = Date.now();
else if (arguments.length > 1) value = Date.UTC.apply(null, arguments);
var d = new Date(value);
// ...
}
答案 3 :(得分:-1)
接受的答案并不理想。我只能希望读这个帖子的人会进一步调查。使用'eval'有很多副作用,我认为你不想在util-lib中使用它。
以下是对你能做什么的粗略看法:
function dateShimmer() {
if(arguments.length === 1){
return new Date(arguments[0]);
}
else if(arguments.length > 1){
return dateArgumentShimmer.apply(null, arguments);
}
return new Date();
}
function dateArgumentShimmer(a1, a2, a3, a4, a5, a6, a7){
//Direct invocation is faster than apply/call
switch(arguments.length){
case 2: return new Date(a1, a2);
case 3: return new Date(a1, a2, a3);
case 4: return new Date(a1, a2, a3, a4);
case 5: return new Date(a1, a2, a3, a4, a5);
case 6: return new Date(a1, a2, a3, a4, a5, a6);
case 7: return new Date(a1, a2, a3, a4, a5, a6, a7);
}
};
Jsfiddle:http://jsfiddle.net/y7Zmr/
答案 4 :(得分:-2)
对我而言,以下是有效的
var args = [];
for(var i = 0; i < arguments.length; i++)
args.push("arguments[" + i + "]");
var d = eval("new Date(" + args.join(",") + ")");