js中对空、null、undefined、0、数字、数组、空对象的严格判断
js 在if中,"", 0, NaN, false,null,undefined都为false
根源:
true ==1 ;//true, false == 0;//true, true == "1";//true, false == "0";//true, false == "";//true, null == undefined;//true
某些情况我们需要对数据做严格的判断,⽐如判断每个变量或参数是不是undefined肯定不能直接if(a)去判断,因为a 如果为“ ‘’ ”, 0, NaN, false,null,undefined”中的任意⼀个就都会进⼊if内从⽽导致bug。本篇博⽂详细介绍判断这些特殊数据类型的正确姿势。
常规判断
var a = "",b= null,c = undefined,d={},e=[];
var f;
check = k=> {
console.log(k+"的数据类型:" +typeof(k));
if(k){
console.log(k+"满⾜条件进⼊判断!")
}else{
console.log(k+"不满⾜条件没有进⼊判断!")
}
}
k=> {
console.log(k+"的数据类型:" +typeof(k));
if(k){
console.log(k+"满⾜条件进⼊判断!")
}else{
console.log(k+"不满⾜条件没有进⼊判断!")
}
}
check(a)
VM194:6 的数据类型:string
VM194:10 不满⾜条件没有进⼊判断!
undefined
check(b)
VM194:6 null的数据类型:object
VM194:10 null不满⾜条件没有进⼊判断!
undefined
check(c)
VM194:6 undefined的数据类型:undefined
VM194:10 undefined不满⾜条件没有进⼊判断!
undefined
check(d)
VM194:6 [object Object]的数据类型:object
VM194:8 [object Object]满⾜条件进⼊判断!
undefined
check(e)
VM194:6 的数据类型:object
VM194:8 满⾜条件进⼊判断!
我们发现如果直接⽤变量进⼊if中判断除了
var d={},e=[]; var f;
被if语句认为是真外其余都认为是假。这样就会带来问题,假如我们要判断某个变量就是undefined或者字符串空,或者null 就会出现问题。
如何判空 “”
这个问题最简单,需要注意的是我们要判断是否为空就要考虑是判断字符串的空还是对象的空,两者是有区别的;
判断字符串空:
var checkStrEmpety = str=>{
var reg = /^\s*$/;
if(typeof(str) === "string" && str === ""){
console.log("我是严格空字符串!")
}
}
上⾯⽅法判断空字符串还缺少⼀步,如果字符串中有空格怎么办?
显然含有空格的的字符串并未复合我们预期,所以还要改:
var checkStrEmpety = str=>{
var reg = /^\s*$/;
if(typeof(str) === "string" && str === "" || st(str)){
console.log("我是严格空字符串!")
}
}
这样我们就做到对严格空字符串的的判断
var checkStrEmpety = str=>{
var reg = /^\s*$/;
if(typeof(str) === "string" && str === "" || st(str)){
console.log("我是严格空字符串!")
}
}
undefined
checkStrEmpety("")
VM1068:4 我是严格空字符串!
undefined
checkStrEmpety("  ")
VM1068:4 我是严格空字符串!
undefined
checkStrEmpety(null)
undefined
判断空对象
1.将json对象转化为json字符串,再判断该字符串是否为"{}"
var data = {};
var b = (JSON.stringify(data) == "{}");
alert(b);//true
如果打括号内有空格呢?
2.for in 循环判断
var obj = {};
var b = function() {
for(var key in obj) {
return false;
}
return true;
}
alert(b());//true
3.jquery的isEmptyObject⽅法
此⽅法是jquery将2⽅法(for in)进⾏封装,使⽤时需要依赖jquery
var data = {};
var b = $.isEmptyObject(data);
alert(b);//true
OwnPropertyNames()⽅法
此⽅法是使⽤Object对象的getOwnPropertyNames⽅法,获取到对象中的属性名,存到⼀个数组中,返回数组对象,我们可以通过判断数组的length来判断此对象是否为空
注意:此⽅法不兼容ie8,其余浏览器没有测试
var data = {};
var arr = OwnPropertyNames(data);
alert(arr.length == 0);//true
5.使⽤ES6的Object.keys()⽅法
与4⽅法类似,是ES6的新⽅法, 返回值也是对象中属性名组成的数组
var data = {};
var arr = Object.keys(data);
alert(arr.length == 0);//true
如何判断0
var exp = 0;
if (typeof(exp) == "number"  && !exp)
{
alert("0");
}
判断 NaN
isNaN()
var tmp = 0/0;
if(isNaN(tmp)){
alert("NaN");
}
如何判断null
checkNull = m=>{
if(typeof(m) == "object" && m==null){
console.log("null")
}
}
或者 ===
如何判断false
typeof array
checkNull = m=>{
if(typeof(m) == "boolean" && m==false){
console.log("null")
}
}
或者 ===
如何判断数组
1.⽤instanceof判断
typeof⽆法⽤于判断数组是否为数组,那么⽤instance运算符来判断。
instanceof运算符可以⽤来判断某个构造函数的prototype属性所指向的對象是否存在于另外⼀个要检测对象的原型链上。在使⽤的时候语法如下:
object instanceof constructor
⽤我的理解来说,就是要判断⼀个Object是不是数组(这⾥不是⼝误,在JavaScript当中,数组实际上也是⼀种对象),如果这个Object 的原型链上能够到Array构造函数的话,那么这个Object应该及就是⼀个数组,如果这个Object的原型链上只能到Object构造函数的话,那么它就不是⼀个数组。
const a = [];
const b = {};
console.log(a instanceof Array);//true
console.log(a instanceof Object);//true,在数组的原型链上也能到Object构造函数
console.log(b instanceof Array);//false
由上⾯的⼏⾏代码可以看出,使⽤instanceof运算符可以分辨数组和对象,可以判断数组是数组。
2.⽤constructor判断
实例化的数组拥有⼀个constructor属性,这个属性指向⽣成这个数组的⽅法。
const a = [];
console.structor);//function Array(){ [native code] }
以上的代码说明,数组是有⼀个叫Array的函数实例化的。
如果被判断的对象是其他的数据类型的话,结果如下:
const o = {};
console.structor);//function Object(){ [native code] }
const r = /^[0-9]$/;
console.structor);//function RegExp() { [native code] }
const n = null;
console.structor);//报错
看到这⾥,你可能会觉得这也是⼀种靠谱的判断数组的⽅法,我们可以⽤以下的⽅式来判断:
const a = [];
console.structor == Array);//true
但是,很遗憾的通知你,constructor属性是可以改写的,如果你⼀不⼩⼼作死改了constructor属性的话,那么使⽤这种⽅法就⽆法判断出数组的真是⾝份了,不推荐啊
3.⽤Object的toString⽅法判断
另⼀个⾏之有效的⽅法就是使⽤String⽅法来判断,每⼀个继承⾃Object的对象都拥有toString的⽅法。
如果⼀个对象的toString⽅法没有被重写过的话,那么toString⽅法将会返回"[object type]",其中的type代表的是对象的类型,根据type 的值,我们就可以判断这个疑似数组的对象到底是不是数组了。
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
从上⾯的代码可以看出,除了对象之外,其他的数据类型的toString返回的都是内容的字符创,只有对象的toString⽅法会返回对象的类型。所以要判断除了对象之外的数据的数据类型,我们需要“借⽤”对象的toString⽅法,所以我们需要使⽤call或者apply⽅法来改变toString⽅法的执⾏上下⽂。
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
String.call(a);//"[object Array]"
String.call(b);//"[object Object]"
String.call(c);//"[object String]"
使⽤apply⽅法也能达到同样的效果:
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
String.apply(a);//"[object Array]"
String.apply(b);//"[object Object]"
String.apply(c);//"[object String]"
我们就可以⽤写⼀个⽅法来判断数组是否为数组:
const isArray = (something)=>{
return String.call(something) === '[object Array]';
}
cosnt a = [];
const b = {};
isArray(a);//true
isArray(b);//false
但是,此⽅法会污染原始数据类型的原型链,不推荐啊。
4.⽤Array对象的isArray⽅法判断
为什么把这种⽅法放在最后讲呢?因为它是我⽬前遇到过的最靠谱的判断数组的⽅法了,当参数为数组的时候,isArray⽅法返回true,当参数不为数组的时候,isArray⽅法返回false。
const a = [];
const b = {};
Array.isArray(a);//true
Array.isArray(b);//false
我试着在调⽤这个⽅法之前重写了String⽅法:
String = ()=>{
console.log(‘Hello Howard’);
}
const a = [];
Array.isArray(a);//true
并不影响判断的结果。
我⼜试着修改了constructor对象:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。