javascript:将参数传递给对象构造函数

时间:2012-07-10 07:41:55

标签: javascript object arguments

我正在编写一个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是日期字符串,则忽略它。 为什么呢?

5 个答案:

答案 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(",") + ")");