2021-04-09【技术】关于空数组和空对象为true的问题

让我们先来看一个问题:

let obj = {}
if(obj){
  console.log("执行了")
}
//执行了

obj明明是空的,为什么会为true呢?
因为空对象或者空数组,都是构造函数的实例化对象,ta们就算没有自定义的属性或者元素,但是其本身是有定义好的属性和方法的。


image.png
js如何判断数组是Array类型
在说明如何判断一个对象为数组类型前,我们先巩固下js的数据类型,js一共有六大数据类型:number、string、object、Boolean、null、undefined。
var str="string";
console.log(typeof str); //string
var num=1;
console.log(typeof num); //number
var bn=false;
console.log(typeof bn); //boolean
var a;
console.log(typeof a); //undfined
var obj = null;
console.log(typeof obj); //object
var doc = document;
console.log(typeof doc);//object
var arr = [];
console.log(arr); //object
var fn = function(){};
console.log(typeof fn); //function   
除了前四个类型外,null、对象、数组返回的都是object类型;对于函数类型返回的则是function,再比如typeof(Date),typeof(eval)等。接下来进入正题,js判断数组类型的方法。
方法一: 使用instanceof方法
instanceof 用于判断一个变量是否某个对象的实例,左边操作数是一个对象,右边操作数是一个函数对象或者函数构造器。原理是通过判断左操作数的对象的原型链上是否具有右操作数的构造函数的prototype属性。
a instanceof b?alert("true"):alert("false")  //注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array。
举一个例子:
var arr=[];
console.log(arr instanceof Array) //返回true
方法二: 使用constructor方法
在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的。
那么判断各种类型的方法:
console.log([].constructor == Array);  //true
console.log({}.constructor == Object);  //true
console.log("string".constructor == String); //true
console.log((123).constructor == Number);  //true
console.log(true.constructor == Boolean);  //true
注意:
使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array ==object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array。
方法三: 使用Object.prototype.toString.call(arr) === '[object Array]'方法
function isArray(o) {
  return Object.prototype.toString.call(o);
}
var arr=[2,5,6,8];
var obj={name:'zhangsan',age:25};
var fn = function () {}
console.log(isArray(arr)); //[object Array]
console.log(isArray(obj)); //[object Object]
console.log(isArray(fn));  //[object function]
方法四:ES5定义了Array.isArray:   -注意此方法IE8不支持
Array.isArray([]) //true

那么如何判断空数组和空对象呢?

在JavaScript中所有数据类型严格意义上都是对象,但实际使用中我们还是有类型之分,如果要判断一个变量是数组还是对象使用typeof搞不定,因为它全都返回object。

使用typeof加length属性

数组有length属性,object没有,而typeof数组与对象都返回object,所以我们可以这么判断

• 判断空数组
• 使用length属性

let arr = []
if(arr.length == 0){
    console.log("数组为空")
}else{
    console.log("数组不为空")
}
///----或者---
var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
var getDataType = function(shopping){
if(typeof shopping == 'object'){
  if( typeof shopping.length == 'number' ){
    return 'Array';
   }else{
    return 'Object';
  }
}
}
console.log(getDataType(shopping)); //Array

• 判断空对象
• 使用Object.keys()将对象属性转为数组
• 然后再使用length属性判断

let obj = {}
if(Object.keys(obj).length == 0){
    console.log("数组为空")
}else{
    console.log("数组不为空")
}

此外,在js中判断数组或者对象的方法

JavaScript isArray() 是 Array 类型的一个静态方法,使用它可以判断一个值是否为数组。

var a = [1,2,3];
console.log(typeof a);  //返回“object”
console.log(Array.isArray(a));  //true

利用JOSN.stringify()
JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。

let data={"name":"ming","age":"12"}
var person = new Object(); 
person.name = "Nicholas"; 
person.age = 29; 
   if(JSON.stringify(person) === '{}'){
          console.log('是对象')
       }else{
          console.log('是数组')
         
        }

---拓展

console.log(typeof NaN)
//number

console.log(typeof Object)
//function

console.log(typeof Object())
// object

console.log(typeof Array)
//"function"

console.log(typeof Array())
//"object"

因为Array本身是js内建的一个构造函数, 构造函数,不实例化,它就只是个函数。
然鹅,当它在调用或者初始化的时候,才会typeof成对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。