判断一个对象是否为数组的4种方法

问题描述

在js中判断数据类型通常使用typeof,但是typeof在判断数组和对象时的结果都是object。

console.log(typeof []);
console.log(typeof {});

在这里插入图片描述
那么,怎么才能区分对象和数组呢?

方法

  1. 判断原型
var obj = {};
var arr = [];
 console.log(arr);
 console.log(obj);

在这里插入图片描述
由上图可知,数组和对象的原型对象不一样,由此可以通过判断原型来判断一个对象是否为数组

var obj = {};
var arr = [];
console.log(Object.getPrototypeOf(obj) === Object.prototype);
console.log(Object.getPrototypeOf(obj) === Array.prototype);

在这里插入图片描述
由此可以得知此种方法可行,但是这种方法是通过检查原型来判断是否为数组,而原型又是可以人为改变的一旦原型改变就可能会失效。

 var obj = {};
 var arr = [];
 Object.setPrototypeOf(obj, Array.prototype);
 console.log(Object.getPrototypeOf(obj) === Object.prototype);
 console.log(Object.getPrototypeOf(obj) === Array.prototype);

在这里插入图片描述
此时arr的原型不是Array.prototype第一个返回的结果为false如此,不能判断是否为数组。

  1. 判断构造函数
    创建对象和创建数组的构造函数不同可以通过此种方法判断一个对象是否为数组。
 var obj = {};
 var arr = [];
 console.log(Object.getPrototypeOf(obj).constructor === Object);
 console.log(Object.getPrototypeOf(obj).constructor === Array);

在这里插入图片描述
由此可见,两个输出结果并不一样,并且也符合我们的认知,通过此种方法也可以判断一个对象是否为数组。
但该种方法与上一种方法的问题一样即当构造函数被修改之后就无法判断真正的数组。

var obj = {};
var arr = [];
Object.getPrototypeOf(obj).constructor = Array;
console.log(Object.getPrototypeOf(obj).constructor === Object);
console.log(Object.getPrototypeOf(obj).constructor === Array);
console.log(Object.getPrototypeOf(arr).constructor === Array);

在这里插入图片描述
由此可见,该方法的缺与上一种方法的一样。
在判断构造函数方法中除了直接判断外还可以使用 instanceof 判断一个对象是否为一个构造函数的实例

var obj = {};
var arr = [];
console.log(obj instanceof Array);
console.log(arr instanceof Array);

在这里插入图片描述
由此可见,该方法也可以判断是否为数组。
3. Array.isArray()
通过Array.isArray()可以判断一个对象是否为数组。

var obj = {};
var arr = [];
console.log(Array.isArray(obj));
console.log(Array.isArray(arr));

在这里插入图片描述
由此可见此种方法可行,那么当我们把其构造函数改变后还会出现和上面一样的情况吗?

var obj = {};
var arr = [];
Object.getPrototypeOf(obj).constructor = Array;
console.log(Array.isArray(obj));
console.log(Array.isArray(arr));

在这里插入图片描述
由此可见,即便将obj的构造函数改为Array也能判断出真正的数组。
4. 用Object.toString()方法判断

var obj = {};
var arr = [];
console.log(obj.toString());
console.log(arr.toString());

在这里插入图片描述
由此可见对象是Object创建的,但是数组的toString()返回的是空。
这是因为js中每个对象都有toString()方法,该方法继承自Object.toString()方法,但数组被重写了,但是我们可以使用call()来调用数组的toString的原始方法来判断。

var obj = {};
var arr = [];
console.log(obj.toString());
console.log(Object.prototype.toString.call(arr));

在这里插入图片描述
由此可见,也可以通过此种方法判断一个对象是否为数组。
那么,如果改变构造函数是否会发生类似之前的情况呢?

var obj = {};
var arr = [];
Object.getPrototypeOf(obj).constructor = Array;
console.log(obj.toString());
console.log(Object.prototype.toString.call(arr));

在这里插入图片描述
由此可见,此时还能正常判断并不会发生此前出现的情况。

使用场景

判断一个对象是否为数组在什么地方使用呢
在进行克隆时,需要判断对象的属性是否为数组,根据结果采取不同的操作。

总结

  1. 判断原型和判断构造函数的方法的结果会因为原型和构造函数的改变发生改变,并不十分稳定。
  2. Array,isArray()和Object.toString()方法较为稳定,较为推荐。
  3. 通常在进行克隆时会用到判断一个对象是否为数组。
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值