js数据类型判断,数组怎么证明是数组,你怎么证明是你自己?

  今天看到一篇文章非常有意思,数组怎么证明是数组,还有最近被爆出来的各种顶替高考的事件。

  你怎么证明是你自己。

  JavaScript有五种方法可以确定一个值到底是什么类型,分别是typeof运算符,constructor法,instanceof运算符,Object.prototype.toString方法以及Array.isArray法。


  1、typeof运算符判断类型

typeof是javascript原生提供的判断数据类型的运算符,它会返回一个表示参数的数据类型的字符串,例如:

let str = 'helloworld'
console.log(typeof(str))  //String

typeof转换结果
在这里插入图片描述

let nu = null;
let obj = {};
let arr = [];
console.log(typeof(nu)); //Object
console.log(typeof(obj)); //Object
console.log(typeof(arr)); //Object

由此可见,typeof不能判断出数组是否为数组,数组归为了object类型。

  2、用instanceof判断

instanceof运算符可以用来判断某个构造函数的prototype属性所指向的對象是否存在于另外一个要检测对象的原型链上。在使用的时候语法如下:

object instanceof constructor

就是要判断一个Object是不是数组(在JavaScript当中,数组实际上也是一种对象),如果这个Object的原型链上能够找到Array构造函数的话,那么这个Object应该及就是一个数组,如果这个Object的原型链上只能找到Object构造函数的话,那么它就不是一个数组。

const arr = [];
const obj = {};
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true,在数组的原型链上也能找到Object构造函数
console.log(obj instanceof Array);//false

由此可见,使用instanceof运算符可以分辨数组和对象,可以判断数组是数组。


  3、用constructor判断

实例化的数组拥有一个constructor属性,这个属性指向生成这个数组的方法。

const arr = [];
console.log(arr.constructor);//function Array(){ [native code] }

由此可见,数组是有一个叫Array的函数实例化的。
判断其他类型

const obj = {};
console.log(obj.constructor);//function Object(){ [native code] }
const reg = /^[0-9]$/;
console.log(reg.constructor);//function RegExp() { [native code] }
const nu = null;
console.log(nu.constructor);//报错

看来这是一个很好的方法,那么我们这样判断:

const arr = [];
console.log(arr.constructor == Array);//true

不过,constructor是可以修改的,修改了就不能做出正确的判断了:

const arr = [];
//改变了原来的constructor属性
a.contrtuctor = Object;
console.log(arr.constructor == Array);//false (no!!!!)
console.log(arr.constructor == Object);//true (god!!!)
console.log(arr instanceof Array);//true (可见这个可以)

所以,有事没事别乱改,最后搞得怀疑人生了。

  4、用Object的toString方法判断

在JavaScript中,每一个继承自Object的对象都拥有toString的方法。

如果一个对象的toString方法没有被重写过的话,那么toString方法将会返回"[object type]",其中的type代表的是对象的类型,根据type的值,我们就可以判断这个疑似数组的对象到底是不是数组了。

const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
a.toString();//"Hello,Howard"
b.toString();//"[object Object]"
c.toString();//"Hello,Howard"

由此可见,只有对象会返回[object Object],会显示它的type,其他的都是字符串,所以我们要调用,它原型上的apply或call来执行toString的上下文。

const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
Object.prototype.toString.call(a);//"[object Array]"
Object.prototype.toString.call(b);//"[object Object]"
Object.prototype.toString.call(c);//"[object String]"

可见返回了它自己的type

apply同样适用

const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
Object.prototype.toString.apply(a);//"[object Array]"
Object.prototype.toString.apply(b);//"[object Object]"
Object.prototype.toString.apply(c);//"[object String]"

这个toString方法也是可以修改的,

let arr = []
Object.prototype.toString = () => {
   arr = '111'
}
Object.prototype.toString.call(arr)  //undefined

还是,有事没事别乱改,最后搞得怀疑人生了。

  5.用Array对象的isArray方法判断

可以说这方法是最nb的一个了,它只认原配,什么小三啊,顶替者它都不管,你只要是数组,就返回true,不是数组就false,就是这么霸道。

let arr1 = []
let arr2 = {}
console.log(Array.isArray(arr1))  //true
console.log(Array.isArray(arr2))  //false

重写一下toString方法

let arr1 = []
let arr2 = {}

Object.prototype.toString = () => {
  arr1 = '111'
}

console.log(Array.isArray(arr1))  //true
console.log(Array.isArray(arr2))  //false

依旧是原配,再搞一下它的constructor

let arr1 = []
let arr2 = {}

Object.prototype.toString = () => {
  arr1 = '111'
}

arr1.constructor = arr2.constructor

console.log(Array.isArray(arr1))  //true
console.log(Array.isArray(arr2))  //false

还是原配,这下可以随便改了,哎,真香。

Array.isArray是ES5标准中增加的方法,部分比较老的浏览器可能会有兼容问题,所以为了增强健壮性,建议还是给Array.isArray方法进行判断,增强兼容性,重新封装的方法如下:

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

文章属转载,仅学习使用,原文链接https://segmentfault.com/a/1190000006150186。

数组都有这么多方法证明自己是数组,你怎么证明你是自己,欢迎评论。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值