4 javascript jquery jquery-plugins
我有自己的jquery插件,用于使用MVC HtmlHelper扩展方法呈现的日期选择器控件.其日期格式为dd/mm/yyyy(澳大利亚日期).
为了更容易从输入构造一个javascript日期对象<input type=text .../>,我重写了构造函数,如下所示:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
然后扩展原型
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.
Run Code Online (Sandbox Code Playgroud)
这允许我这样做:
this.selectedDate = new Date(this.input.val());
Run Code Online (Sandbox Code Playgroud)
哪里this.selectedDate是我可以使用的有效javascript日期,并this.input正确回发到我的控制器.
在测试js文件中工作时,所有工作都按预期工作,但是当我将代码复制到插件文件中时,它全部崩溃并烧毁.经过多次拔毛,我意识到我已经在方法之前切割并粘贴了构造函数.一旦我将构造函数放在方法之后(根据测试文件),它就会再次开始工作.
我的第一个问题是为什么我得到undefined不是函数错误?当然(但显然不是!)被覆盖的构造函数返回一个javascript日期对象,因此如果在构造函数之后声明原型方法应该有效.
我的第二个相关问题是,是否有一种方法可以将重写的构造函数"私有"到插件中.如果插件已加载并且您进入myDate = new Date()控制台,它将返回Invalid Date(这是我想要的插件),但会让插件的另一个用户感到困惑.
如果你想在插件中使用不同的行为,那么Date为什么不用Date()你自己的构造函数继承对象,而只是在你想要不同的行为时使用那个构造函数,而不是替换构造函数.
因此,您将Date()保持构造函数不变,以便其他所有人都能获得正常的Date行为.然后,ValidDate()当你想要特殊行为时,你会有自己的构造函数(调用它或任何你想要的东西).
这是更正常的面向对象行为.当您想要派生/特殊行为时继承现有对象,同时仍保持原始对象不受正常使用的影响.
此外,看起来您的构造函数只有在传递一个/单独的字符串时才有效.如果Date()使用构造函数的任何其他形式的合法参数,例如您在.clone()方法中使用的那些,那么您将尝试将其作为字符串处理.它看起来像你应该测试构造函数参数是否是一个字符串,只有它给它特殊处理.这样,其他合法构造函数参数(例如getTime()从另一个Date对象传入结果)仍将继续有效.
这是处理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;
}
Run Code Online (Sandbox Code Playgroud)
工作示例:http://jsfiddle.net/jfriend00/B25LX/