How to check whether an object is a date?
我在网页上发现了一个令人讨厌的错误:
date.GetMonth() is not a function
所以,我想我做错了什么。变量
1 2 3 4 5 | function getFormatedDate(date) { if (date) { var month = date.GetMonth(); } } |
所以,如果我想写防御代码并防止日期(不是一个)被格式化,我该怎么做呢?
谢谢!
更新:我不想检查日期的格式,但我想确保传递给方法
作为鸭子打字的替代方法
1 | typeof date.getMonth === 'function' |
您可以使用
1 | date instanceof Date |
如果对象通过帧边界,这将失败。
解决这个问题的方法是通过
1 | Object.prototype.toString.call(date) === '[object Date]' |
您可以使用以下代码:
1 | (myvar instanceof Date) // returns true or false |
函数是
无论如何,您可以通过这样做来检查对象是否具有GetMonth属性。它不一定意味着对象是日期,只是具有getMonth属性的任何对象。
1 2 3 | if (date.getMonth) { var month = date.getMonth(); } |
为了检查该值是否为标准JS日期对象的有效类型,可以使用此谓词:
1 2 3 | function isValidDate(date) { return date && Object.prototype.toString.call(date) ==="[object Date]" && !isNaN(date); } |
- 绕过具有相同构造函数名称的用户定义对象类型(例如:"日期")。
- 与
instanceof 或Date.prototype.isPrototypeOf 不同,它在不同的JS上下文(例如iframes)中工作。
如上所述,在使用函数之前,检查函数是否存在可能是最简单的。如果您真的关心它是一个
1 2 3 4 | function isValidDate(value) { var dateWrapper = new Date(value); return !isNaN(dateWrapper.getDate()); } |
如果值是
对于所有类型,我编写了一个对象原型函数。可能对你有用
1 2 3 4 5 6 7 8 9 10 11 12 13 | Object.prototype.typof = function(chkType){ var inp = String(this.constructor), customObj = (inp.split(/\({1}/))[0].replace(/^ /,'').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; } |
现在您可以检查以下任何类型:
1 2 3 4 | var myDate = new Date().toString(), myRealDate = new Date(); if (myRealDate.typof('Date')) { /* do things */ } alert( myDate.typof() ); //=> String |
[2013年3月编辑]基于不断深入的洞察力,这是一种更好的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
underlinejs和lodash有一个名为
我发现最好的方法是:
1 2 3 4 | !isNaN(Date.parse("some date test")) // !isNaN(Date.parse("22/05/2001")) // true !isNaN(Date.parse("blabla")) // false |
您可以检查特定于日期对象的函数是否存在:
1 2 3 4 5 | function getFormatedDate(date) { if (date.getMonth) { var month = date.getMonth(); } } |
你也可以用短表格
1 2 3 4 | function getClass(obj) { return {}.toString.call(obj).slice(8, -1); } alert( getClass(new Date) ); //Date |
或者像这样:
1 | (toString.call(date)) == 'Date' |
我一直在使用一种更简单的方法,但不确定这是否只在ES6中可用。
1 2 3 4 5 6 | let a = {name:"a", age: 1, date: new Date("1/2/2017"), arr: [], obj: {} }; console.log(a.name.constructor.name); //"String" console.log(a.age.constructor.name); //"Number" console.log(a.date.constructor.name); //"Date" console.log(a.arr.constructor.name); //"Array" console.log(a.obj.constructor.name); //"Object" |
但是,这不会在空值或未定义值上工作,因为它们没有构造函数。
如果是日期,此函数将返回
1 2 3 | function isDate(myDate) { return myDate.constructor.toString().indexOf("Date") > -1; } |
使用try/catch的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | function getFormatedDate(date = new Date()) { try { date.toISOString(); } catch (e) { date = new Date(); } return date; } console.log(getFormatedDate()); console.log(getFormatedDate('AAAA')); console.log(getFormatedDate(new Date('AAAA'))); console.log(getFormatedDate(new Date(2018, 2, 10))); |
实际日期为
1 2 3 4 5 | function getFormatedDate(date) { if (date && date.getMonth && date.getMonth.call) { var month = date.getMonth(); } } |
还有另一个变种:
1 | Date.prototype.isPrototypeOf(myDateObject) |
你不能用一下吗
1 2 3 4 5 | function getFormatedDate(date) { if (date.isValid()) { var month = date.GetMonth(); } } |