【问题标题】:javascript: pass arguments to object constructorjavascript:将参数传递给对象构造函数
【发布时间】:2012-07-09 15:48:10
【问题描述】:

我正在编写一个 jquery 库,我需要实现 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,但无论如何我都会得到当前日期。 如果 arguments 是日期字符串,则将其忽略。 为什么?

【问题讨论】:

标签: javascript object arguments


【解决方案1】:
var args = Array.prototype.concat.apply([null], arguments);
return new (Function.prototype.bind.apply(Date, args));

如果您的目标浏览器不支持 ECMAScript 5 Function.prototype.bind,则代码将无法运行。不过可能性不大,请参阅compatibilty table

【讨论】:

  • 不错!但是您应该添加一个通知,这不太可能适用于任何bind shims。
【解决方案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;
};

【讨论】:

    【解决方案3】:

    一些注意事项:

    • 切勿使用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);
    
        // ...
    }
    

    【讨论】:

      【解决方案4】:

      接受的答案并不理想。我只能希望任何阅读此主题的人都会进一步调查。使用“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/

      【讨论】:

        【解决方案5】:

        对我来说可以,以下是工作

        var args = [];
        for(var i = 0; i < arguments.length; i++)
           args.push("arguments[" + i + "]");
        
        var d = eval("new Date(" + args.join(",") + ")");   
        

        【讨论】:

        • 我认为你不应该在这里使用 eval ,因为它很慢。你真的需要创建自己的 Date 函数吗?
        • 是的,不仅是 Date 这对其他对象有用。另一方面,评估有多慢?大多数人都拥有具有 icore pentium 和大量内存的现代机器。我认为这样的机器不会有任何问题。
        • 作为参数传入:); console.log("evil &gt;:("
        猜你喜欢
        • 2014-07-15
        • 2013-12-12
        • 2011-11-28
        • 2014-06-04
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 1970-01-01
        • 2012-11-14
        相关资源
        最近更新 更多