我在网页上有一个恼人的错误:
date.GetMonth()不是函数
所以,我想我做错了什么.变量date
不是类型的对象Date
.如何在Javascript中检查数据类型?我试图添加一个if (date)
,但它不起作用.
function getFormatedDate(date) { if (date) { var month = date.GetMonth(); } }
所以,如果我想编写防御性代码并防止日期(不是一个)被格式化,我该怎么做?
谢谢!
更新:我不想检查日期的格式,但我想确保传递给方法的参数getFormatedDate()
是类型Date
.
作为鸭子打字的替代品
typeof date.getMonth === 'function'
你可以使用instanceof
运算符,即它也会对无效日期返回true,例如new Date('random_string')
也是Date的实例
date instanceof Date
如果对象跨帧边界传递,则会失败.
解决方法是通过检查对象的类
Object.prototype.toString.call(date) === '[object Date]'
您可以使用以下代码:
(myvar instanceof Date) // returns true or false
为了检查值是否是标准JS-date对象的有效类型,您可以使用此谓词:
function isValidDate(date) { return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date); }
date
检查是否参数不是一个falsy值(undefined
,null
,0
,""
等.)
Object.prototype.toString.call(date)
返回给定对象类型的本地字符串表示形式 - 在我们的示例中"[object Date]"
.因为date.toString()
重写它的父方法,我们需要.call
或直接.apply
从Object.prototype
哪个方法...
绕过具有相同构造函数名称的用户定义的对象类型(例如:"Date")
与instanceof
或相反,在不同的JS上下文(例如iframe)中工作Date.prototype.isPrototypeOf
.
!isNaN(date)
最后检查价值是否不是Invalid Date
.
功能是getMonth()
,而不是GetMonth()
.
无论如何,您可以通过执行此操作来检查对象是否具有getMonth属性.它并不一定意味着对象是Date,只是具有getMonth属性的任何对象.
if (date.getMonth) { var month = date.getMonth(); }
如上所述,在使用之前检查函数是否存在可能是最简单的.如果你真的关心它是一个Date
,而不只是一个具有getMonth()
函数的对象,试试这个:
function isValidDate(value) { var dateWrapper = new Date(value); return !isNaN(dateWrapper.getDate()); }
如果它是a Date
,则会创建值的克隆,或创建无效日期.然后,您可以检查新日期的值是否无效.
对于所有类型我都编写了一个Object原型函数.它可能对你有用
Object.prototype.typof = function(chkType){ var inp = String(this.constructor), customObj = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9), regularObj = Object.prototype.toString.apply(this), thisType = regularObj.toLowerCase() .match(new RegExp(customObj.toLowerCase())) ? regularObj : '[object '+customObj+']'; return chkType ? thisType.toLowerCase().match(chkType.toLowerCase()) ? true : false : thisType; }
现在你可以检查这样的任何类型:
var myDate = new Date().toString(), myRealDate = new Date(); if (myRealDate.typof('Date')) { /* do things */ } alert( myDate.typof() ); //=> String
[ 编辑2013年3月 ]基于进步的洞察力,这是一个更好的方法:
Object.prototype.is = function() { var test = arguments.length ? [].slice.call(arguments) : null ,self = this.constructor; return test ? !!(test.filter(function(a){return a === self}).length) : (this.constructor.name || (String(self).match ( /^function\s*([^\s(]+)/im) || [0,'ANONYMOUS_CONSTRUCTOR']) [1] ); } // usage var Some = function(){ /* ... */} ,Other = function(){ /* ... */} ,some = new Some; 2..is(String,Function,RegExp); //=> false 2..is(String,Function,Number,RegExp); //=> true 'hello'.is(String); //=> true 'hello'.is(); //-> String /[a-z]/i.is(); //-> RegExp some.is(); //=> 'ANONYMOUS_CONSTRUCTOR' some.is(Other); //=> false some.is(Some); //=> true // note: you can't use this for NaN (NaN === Number) (+'ab2').is(Number); //=> true
UnderscoreJS和Lodash有一个调用的函数.isDate()
这似乎正是你所需要的.这是值得看各自的实现:Lodash而isDate,UnderscoreJs
我发现的最好方法是:
!isNaN(Date.parse("some date test")) // !isNaN(Date.parse("22/05/2001")) // true !isNaN(Date.parse("blabla")) // false