javascript - 覆盖javascript日期构造函数

标签 javascript jquery jquery-plugins

我有自己的 jquery 插件,用于使用 MVC HtmlHelper 扩展方法呈现的日期选择器控件。它的日期格式为 dd/mm/yyyy(澳大利亚日期)。

为了更容易地从输入 <input type=text .../> 构造一个 javascript 日期对象,我按如下方式覆盖了构造函数:

// Save the default constructor 
var _DefaultDateConstructor = Date.prototype.constructor;
// Constructor
Date = function () {
  var date = new _DefaultDateConstructor();
  if (arguments === undefined || arguments.length === 0) {
    // Ensure an invalid date is returned
    date.setDate(Number.NaN);
    return date;
  }
  // Get the arguments
  var args = arguments[0].toString().split(/[\/ ]/);
  // Set date properties
  date.setMilliseconds(0);
  date.setSeconds(0);
  date.setMinutes(0);
  date.setHours(0);
  date.setDate(parseInt(args[0], 10));
  date.setMonth(parseInt(args[1], 10) - 1);
  date.setFullYear(parseInt(args[2], 10));
  return date;
}

然后扩展原型(prototype)

Date.prototype.isValid = function () {
  return !isNaN(this.getTime());
}

Date.prototype.clone = function () {
  return new _DefaultDateConstructor(this.getTime());
}

// More methods to return day name, month name etc. for formatting the display.

这允许我这样做:

this.selectedDate = new Date(this.input.val());

哪里this.selectedDate是我可以使用的有效 javascript 日期,this.input正确回发到我的 Controller 。

在测试 js 文件中工作时,一切都按预期工作,但是当我将代码复制到插件文件中时,它全部崩溃并烧毁。经过多次摸索之后,我意识到我已经在方法之前剪切并粘贴了构造函数。一旦我将构造函数放在方法之后(根据测试文件),它就会再次开始工作。

我的第一个问题是为什么我得到undefined is not a function错误?当然(但显然不是!)重写的构造函数返回一个 javascript 日期对象,因此如果在构造函数之后声明,原型(prototype)方法应该可以工作。

我的第二个相关问题是,有没有办法让重写的构造函数对插件“私有(private)”。如果插件已加载并且您输入 myDate = new Date()在控制台中,它返回 Invalid Date (这就是我想要的插件)但会让插件的其他用户感到困惑。

最佳答案

如果您只想在您的插件中使用不同的行为,那么与其替换 Date 构造函数,不如从 Date() 对象继承使用您自己的构造函数,并在需要不同行为时使用该构造函数。

因此,您将保留 Date() 构造函数不变,这样其他人就会得到正常的 Date 行为。然后,您将拥有自己的构造函数(将其称为 ValidDate() 或任何您想要的名称),当您需要特殊行为时可以使用它。

这是更正常的面向对象行为。当您想要派生/特殊行为时从现有对象继承,同时仍然保持原始对象不变以供正常使用。


另外,看起来你的构造函数只有在你传递给它一个 / 分隔的字符串时才有效。如果使用了 Date() 构造函数的任何其他形式的合法参数,例如您在 .clone() 方法中使用的参数,那么您将尝试处理它作为一个字符串。在我看来,您应该测试构造函数参数是否为字符串,如果是,则只对其进行特殊处理。这样,其他合法的构造函数参数(例如从另一个 Date 对象传入 getTime() 结果)仍将继续有效。


这是处理 Date() 对象的局限性/奇怪之处的一种方法:

function ValidDate(a,b,c,d,e,f,g) {
    var date;
    if (arguments.length === 0) {
        // your special behavior here
        date = new Date();
    }
    else if (arguments.length === 1) {
        if (typeof a === "string") {
           // add your own constructor string parsing here
        } else {
            // normal default processing of single constructor argument
            date = new Date(a);
        }
    } else {
        // must be this form: new Date(year, month, day, hour, minute, second, millisecond);
        // the picky Date() constructor doesn't handle undefined
        // for an argument so we pass zero for any missing argument
        c = c || 0;
        d = d || 0;
        e = e || 0;
        f = f || 0;
        g = g || 0;
        date = new Date(a,b,c,d,e,f,g);
    }

   // add custom methods to this Date object
   date.isValid = function() {
       return !isNaN(this.getTime());
   }

   date.clone = function() {
       return ValidDate(this.getTime());
   }

   return date;
}

工作示例:http://jsfiddle.net/jfriend00/B25LX/

关于javascript - 覆盖javascript日期构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23556387/

相关文章:

javascript - Backbone - 插入 JavaScript 来操作 DOM 的最佳位置在哪里

javascript - Datatables.net json数据加载

javascript - 我单击时选择了多个元素,现在我只想要其中一个(单击功能类似于浏览器中的检查器)

jquery - Jvectormap - 设置每个区域的悬停颜色?

jquery-mobile-960 流体布局在 <li> 内使用时散布网格 block

jquery - 将 jQuery 插件转换为 WordPress 插件

javascript - 默认 "All"选项不适用于 ng-option 选择列表

php - 无法理解为什么我的网站一直导航到其索引页面?

Javascript 用 a-f 替换数字 10-15

javascript - 附加具有多个单引号的代码