4

我正在编写一个 jquery lib,我需要实现 Datetime 函数。我需要创建一个 .Date() 函数,它返回一个新的 Date 对象。

如何将我的 .Date(args) 函数的参数传递给 Date 对象构造函数以创建新的日期对象?

我试过这样的东西,我是插件命名空间,me=$.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,但无论如何我都会得到当前日期。如果参数是日期字符串,则忽略它。为什么?

4

5 回答 5

8
var args = Array.prototype.concat.apply([null], arguments);
return new (Function.prototype.bind.apply(Date, args));

如果您的目标浏览器不支持 ECMAScript 5 Function.prototype.bind,则代码将不起作用。但可能性不大,请参阅兼容性表

于 2013-08-14T19:05:37.830 回答
2
Date.prototype.constructor

挺没用的,直接用Date——函数就是构造函数。

.apply(null, ...

您将需要在该类型的新创建对象上应用构造函数,而不是在null. 请参阅将 .apply() 与“new”运算符一起使用。这可能吗?

但是,不可能应用真正的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;
};
于 2012-07-10T07:48:09.333 回答
0

几点注意事项:

  • 千万不要用eval,很危险。
  • bind并不总是可用的,正如所指出的,垫片的工作方式不同。
  • Date.UTC还接受一个变量参数列表并返回一个可由Date构造函数使用的标量。
  • apply只需要一个像对象这样的数组,而不是一个实际的数组,所以arguments就足够了。

所以这是我首选的、浏览器安全的、完全可变的方法。请注意它如何处理没有参数的Date.now(). 传递 anull与没有参数不同,因此允许执行相同的操作。

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);

    // ...
}
于 2014-07-14T18:47:46.640 回答
-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/

于 2014-01-30T02:23:04.990 回答
-2

对我来说好的,以下工作

var args = [];
for(var i = 0; i < arguments.length; i++)
   args.push("arguments[" + i + "]");

var d = eval("new Date(" + args.join(",") + ")");   
于 2012-07-10T12:21:59.820 回答