简体   繁体   English

覆盖javascript日期构造函数

[英]Override javascript date constructor

I have my own jquery plugin for a date picker control that is rendered with a MVC HtmlHelper extension method. 我有自己的jquery插件,用于使用MVC HtmlHelper扩展方法呈现的日期选择器控件。 Its for dates in the format dd/mm/yyyy (Australian date). 其日期格式为dd / mm / yyyy(澳大利亚日期)。

To make it easier construct a javascript date object from the input <input type=text .../> , I overrode the constructor as follows: 为了更容易从输入<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;
}

and then extended the 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.

Which allows me do do this: 这允许我这样做:

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

where this.selectedDate is a valid javascript date I can work with, and this.input posts back correctly to my controller. this.selectedDate是我可以使用的有效javascript日期, this.input正确地回发给我的控制器。

When working in a test js file, all worked as intended, but when I copied the code into the plugin file, it all crashed and burned. 在测试js文件中工作时,所有工作都按预期工作,但是当我将代码复制到插件文件中时,它全部崩溃并烧毁。 After much hair pulling, I realised that I had cut and pasted the constructor before the methods. 经过多次拔毛,我意识到我已经在方法之前切割并粘贴了构造函数。 Once I put the constructor after the methods (as per the test file) it started working again. 一旦我将构造函数放在方法之后(根据测试文件),它就会再次开始工作。

My first question is why was I getting undefined is not a function errors? 我的第一个问题是为什么我得到undefined不是函数错误? Surely (but obviously not!) the overridden constructor is returning a javascript date object so the prototype methods should work if declared after the constructor. 当然(但显然不是!)被覆盖的构造函数返回一个javascript日期对象,因此如果在构造函数之后声明原型方法应该有效。

My second related question is, is there a way to have the overridden constructor 'private' to the plugin. 我的第二个相关问题是,是否有一种方法可以将重写的构造函数“私有”到插件中。 If the plugin is loaded and you enter myDate = new Date() in the console, it returns Invalid Date (which is what I want for the plugin) but would be confusing for another user of the plugin. 如果加载插件并在控制台中输入myDate = new Date() ,它将返回Invalid Date (这是我想要的插件),但会让插件的另一个用户感到困惑。

If you want a different behavior just for use in your plugin, then rather than replace the Date constructor, why don't you inherit from the Date() object with your own constructor and just use that constructor when you want the different behavior. 如果你想在插件中使用不同的行为,那么为什么不用你自己的构造函数继承Date()对象,而只是在你想要不同的行为时使用那个构造函数,而不是替换Date构造函数。

So, you'd leave the Date() constructor unchanged so everyone else would get the normal Date behavior. 因此,您将保持Date()构造函数不变,以便其他所有人都能获得正常的Date行为。 And, then you'd have your own constructor (call it ValidDate() or whatever you want) that you would use when you want the special behavior. 然后,当你想要特殊行为时,你将拥有自己的构造函数(称之为ValidDate()或任何你想要的)。

This is the more normal object oriented behavior. 这是更正常的面向对象行为。 Inherit from an existing object when you want a derived/special behavior while still leaving the original object untouched for normal usage. 当您想要派生/特殊行为时继承现有对象,同时仍保持原始对象不受影响以进行正常使用。


Also, it looks like your constructor only works if you pass it a / separated string. 此外,看起来您的构造函数只有在传递/分隔字符串时才有效。 If any of the other forms of legal arguments to the Date() constructor are used such as what you use in your .clone() method, then you will try to process it as a string. 如果使用Date()构造函数的任何其他形式的合法参数,例如您在.clone()方法中使用的.clone() ,那么您将尝试将其作为字符串处理。 It looks to me like you should test if the constructor argument is a string and only give it special processing if it is. 它看起来像你应该测试构造函数参数是否是一个字符串,只有它给它特殊处理。 That way, other legal constructor arguments such as passing in the getTime() result from another Date object will still continue to work. 这样,其他合法的构造函数参数,例如从另一个Date对象传入getTime()结果仍然可以继续工作。


Here's one way to do it that deals with the limitations/oddities of the Date() object: 这是处理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;
}

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

My first question is why was I getting undefined is not a function errors? 我的第一个问题是为什么我得到undefined不是函数错误? Surely (but obviously not!) the overridden constructor is returning a javascript date object so the prototype methods should work if declared after the constructor. 当然(但显然不是!)被覆盖的构造函数返回一个javascript日期对象,因此如果在构造函数之后声明原型方法应该有效。

If you override the constructor first, the prototype methods are added to the new constructor's prototype. 如果首先覆盖构造函数,则将原型方法添加到新构造函数的原型中。 But the constructor itself returns a regular Date object, which has a different prototype without those methods. 但是构造函数本身返回一个常规的Date对象,它有一个不同的原型,没有那些方法。

My second related question is, is there a way to have the overridden constructor 'private' to the plugin. 我的第二个相关问题是,是否有一种方法可以将重写的构造函数“私有”到插件中。 If the plugin is loaded and you enter myDate = new Date() in the console, it returns Invalid Date (which is what I want for the plugin) but would be confusing for another user of the plugin. 如果加载插件并在控制台中输入myDate = new Date(),它将返回Invalid Date(这是我想要的插件),但会让插件的另一个用户感到困惑。

No, there isn't. 不,没有。 Overriding the Date constructor means overriding a global variable. 覆盖Date构造函数意味着覆盖全局变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM