2012-07-10 222 views
4

我在写一个jQuery lib,我需要实现Datetime函数。 我需要创建一个.Date()函数,它返回一个新的Date对象。javascript:将参数传递给对象构造函数

如何将我的.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的论点,但我在任何情况下,当前的日期得到。 如果参数是一个日期字符串,它将被忽略。 为什么?

+1

'Date.prototype.constructor'是完全等效于刚'Date' – lanzz 2012-07-10 07:46:15

+0

的[通过调用实例化prototype.constructor.apply JavaScript对象]可以重复(http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply) – Jon 2012-07-10 07:47:00

+0

查看接受的答案。 – Jon 2012-07-10 07:47:22

回答

-2

确定为我下面的是工作

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

var d = eval("new Date(" + args.join(",") + ")"); 
+0

我不认为你应该在这里使用eval,因为它的缓慢。你真的需要创建自己的日期函数吗? – Bergi 2012-07-11 19:13:00

+0

是的,不仅日期这将是有用的其他对象。另一方面eval有多慢?大多数人拥有icore pentium和大量内存的现代化机器。我不认为这样的机器会有任何问题。 – demosthenes 2012-07-13 12:16:45

+1

作为参数传入:'); console.log(“evil> :(''' – 2015-11-14 05:49:20

2
Date.prototype.constructor 

还是蛮有用的,只是使用Date - 功能构造。

.apply(null, ... 

您将需要该类型的新创建的对象上应用的构造函数,而不是null。见Use of .apply() with 'new' operator. Is this possible?

然而,这是不可能的应用真正Date构造函数(用于new功能),因为EcmaScript的规定,当Date被称为函数必须返回当前UTC时间。


无论如何,你不应该需要这个。而不是接收一堆参数(可变大小),你应该指定一个参数为一个对象。该功能的用户可以建立如何想要的。

你奇怪的功能似乎与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; 
}; 
+0

感谢Bergi的链接! – demosthenes 2012-07-10 12:22:47

+0

是的,这是真的[isNaN(d)],感谢提示 – demosthenes 2012-07-11 16:16:30

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

如果你的目标浏览器不支持的ECMAScript 5 Function.prototype.bind,代码夺得”工作。这不太可能,请参阅compatibilty table

+0

不错!但是你应该添加一个通知,这对于任何'bind'垫片都不太可能起作用。 – Bergi 2013-08-14 19:47:41

-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/

0

的几个注意事项:

  • 切勿使用eval,这是危险的。
  • bind并不总是可用的,正如指出的那样,垫片的工作原理不一样。
  • Date.UTC也采用可变参数列表并返回可用于构造函数的标量。
  • 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); 

    // ... 
} 
相关问题